Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 指针指向Void的内存分配_C_Pointers_Memory_Memory Management_Void Pointers - Fatal编程技术网

C 指针指向Void的内存分配

C 指针指向Void的内存分配,c,pointers,memory,memory-management,void-pointers,C,Pointers,Memory,Memory Management,Void Pointers,假设我有一个包含void**成员的结构。此成员用作指向数据通道的指针数组。数据类型是不相关的。下面是一个示例,我想为这个2D数组分配内存,然后将通道指针与其内存相关联 #define N_CHANNELS (/*Number of data channels*/) #define N_SAMPLES (/*Number of data samples per channel*/) typedef /*Some data type*/ DATA_TYPE; void **ppdata; /*Co

假设我有一个包含void**成员的结构。此成员用作指向数据通道的指针数组。数据类型是不相关的。下面是一个示例,我想为这个2D数组分配内存,然后将通道指针与其内存相关联

#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);
}
i、 例如,这个分配是否与我以后访问内存的方式兼容

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

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

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

您的总体想法在我看来还行,但是
(void**)malloc(sizeof(DATA_TYPE*)*N_CHANNELS)
让我感觉到了蜘蛛的刺痛。为指向
数据类型的
N\u通道的
指针数组分配空间,但将其视为指向
void
的指针数组。C中没有任何东西可以保证
void*
数据类型*
具有相同的大小和表示形式(除非
数据类型
恰好是
字符
)。因此,您随后对
ppdata[0]=…
的赋值在作为
数据类型*
的位时可能会产生垃圾(这是您稍后通过
ptr
执行的操作)

我更喜欢这样:

/* 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;

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

/* 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]);

也就是说,只需从
I
j
手动计算索引,我觉得您的总体想法还可以,但是
(void**)malloc(sizeof(DATA_TYPE*)*N_CHANNELS)
让我的蜘蛛感觉刺痛。为指向
数据类型的
N\u通道的
指针数组分配空间,但将其视为指向
void
的指针数组。C中没有任何东西可以保证
void*
数据类型*
具有相同的大小和表示形式(除非
数据类型
恰好是
字符
)。因此,您随后对
ppdata[0]=…
的赋值在作为
数据类型*
的位时可能会产生垃圾(这是您稍后通过
ptr
执行的操作)

我更喜欢这样:

/* 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;

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

/* 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]);

也就是说,只要从
I
j

@4386427手动计算索引,我已经为所有通道分配了内存,还有第二条malloc()语句,因为我需要所有通道的数据都在连续内存中。我在for循环中为ppdata[1]、…、ppdata[N_通道-1]分配适当的地址。
typedef DATA_-TYPE
typedef int DATA_TYPE这是在编译时确定的。@BLUEPIXY类型定义仅用于说明。在这种思想的应用程序中,数据类型将以另一种方式传递。虽然
void*
是C中的“通用”指针类型,但事实证明
void**
不能作为指向指针的通用指针进行移植。因此,您的行
DATA\u TYPE**ptr=(DATA\u TYPE**)ppdata
是可疑的。请参见@4386427循环的目的是初始化,而不是取消引用。@4386427我已经为所有通道分配了内存,其中包含第二条malloc()语句,因为我需要所有通道的数据都在连续内存中。我在for循环中为ppdata[1]、…、ppdata[N_通道-1]分配适当的地址。
typedef DATA_-TYPE
typedef int DATA_TYPE这是在编译时确定的。@BLUEPIXY类型定义仅用于说明。在这种思想的应用程序中,数据类型将以另一种方式传递。虽然
void*
是C中的“通用”指针类型,但事实证明
void**
不能作为指向指针的通用指针进行移植。因此,您的行
DATA\u TYPE**ptr=(DATA\u TYPE**)ppdata
是可疑的。参见@4386427循环的目的是初始化,而不是取消引用。问题是关于分配。数据类型仅用于说明。我遇到的问题是,您的代码不能像您编写的那样工作。因此,当询问包含
sizeof(DATA\u TYPE)
的代码行的正确性时,该代码本质上是不正确的。当您转换为
数据类型
时,这同样是无法工作的。如果这些都是您知道的,但以这种方式编写代码是为了“说明”,那么回答者就很难找出代码的哪些部分是故意不正确的,哪些可能是您实际尝试的内容的缺陷。为了清楚起见,我对问题进行了编辑。如果你能回答关于分配的问题,我将不胜感激。问题是关于分配的。数据类型仅用于说明。我遇到的问题是,您的代码不能像您编写的那样工作。因此,当询问包含
sizeof(DATA\u TYPE)
的代码行的正确性时,该代码本质上是不正确的。当您转换为
数据类型
时,这同样是无法工作的。如果这些都是您知道的,但以这种方式编写代码是为了“说明”,那么回答者就很难找出代码的哪些部分是故意不正确的,哪些可能是您实际尝试的内容的缺陷。为了清楚起见,我对问题进行了编辑。如果你能提供一个关于所述问题的答案