内存分配,指针指向无效

假设我有一个void **成员的结构。 这个成员可以作为数据通道的指针数组。 数据类型是不相关的。 以下是我想如何为这个二维数组分配内存然后将通道指针与其内存相关联的示例。

#define N_CHANNELS (/*Number of data channels*/)
#define N_SAMPLES (/*Number of data samples per channel*/)
typedef /*Some data type*/ DATA_TYPE;

void **ppdata; /*Conceptual struct member*/

/*Allocate memory for array of data channels */
ppdata = (void **) malloc(sizeof(DATA_TYPE *) * N_CHANNELS);
ppdata[0] = malloc(sizeof(DATA_TYPE) * N_CHANNELS * N_SAMPLES);

/*Cast for pointer arithmetic and data access*/
DATA_TYPE **ptr = (DATA_TYPE **) ppdata;

/*Associate channels with their memory*/
int alloc_index;
for (alloc_index = 0; alloc_index < N_CHANNELS; alloc_index++)
{
     ptr[alloc_index] = (*ptr + alloc_index * N_SAMPLES);
}

所以,问题就出现了:这个解除引用和分配行为是否像我所假设的那样行事?

ppdata[0] = malloc(sizeof(DATA_TYPE) * N_CHANNELS * N_SAMPLES);

即,这种分配与我以后访问内存的方式是否兼容?

DATA_TYPE **ptr = (DATA_TYPE **) ppdata;
...
ptr[alloc_index] = (*ptr + alloc_index * N_SAMPLES);

你的一般想法对我来说看起来(void **) malloc(sizeof(DATA_TYPE *) * N_CHANNELS) ,但是(void **) malloc(sizeof(DATA_TYPE *) * N_CHANNELS)使我的蜘蛛感觉很兴奋。 您为N_CHANNELS指针的数组分配空间给DATA_TYPE ,但将其视为指向void的指针数组。 C中没有任何东西可以保证void *DATA_TYPE *具有相同的大小和表示形式(除非DATA_TYPE恰好是char )。 因此,当您查看DATA_TYPE * (这是您通过ptr后来做的)的位时,您对ppdata[0] = ...的后续赋值可能会产生垃圾。

我更喜欢这样:

/* overflow check omitted */
DATA_TYPE *storage = malloc(N_CHANNELS * N_SAMPLES * sizeof *storage);
/* error check omitted */

/* overflow check omitted */
DATA_TYPE **pointers = malloc(N_CHANNELS * sizeof *pointers);
/* error check omitted */

for (size_t i = 0; i < N_CHANNELS; i++) {
    pointers[i] = storage + i * N_SAMPLES;
}

/* struct member */
void *pdata = pointers;

然后,您可以通过执行以下操作来恢复指针数组:

DATA_TYPE **pointers = pdata;
do_stuff_with(pointers[i][j]);

从技术上讲,你不需要一个单独的指针数组,因为你有一个很好的矩形数组。 你可以这样做:

/* overflow check omitted */
DATA_TYPE *storage = malloc(N_CHANNELS * N_SAMPLES * sizeof *storage);
/* error check omitted */

/* struct member */
void *pdata = storage;

后来:

DATA_TYPE *storage = pdata;
do_stuff_with(storage[i * N_SAMPLES + j]);

也就是手动计算ij的索引。


C不支持在运行时发现数据类型的能力。 如果要使用通用数据类型,则必须传入一个变量,用于定义要使用的数据类型的字节数。

链接地址: http://www.djcxy.com/p/80229.html

上一篇: Memory Allocation With Pointer to Pointer to Void

下一篇: How much memory is allocated to an object of this class?