5

我有一个 void-Pointers 数组并想要访问元素(初始化它们),但它不起作用:

void* anyptr = ...; //a pointer to something
void* arr = (void*)malloc(sizeof(void*)*10);

int i=0;
for(i=0; i<10; i++)
   *(arr+i) = anyptr; //dont work, (arr+n) = anyptr; doesn´t work too

我想,这不起作用的原因是左侧是元素 i 的结果。但我不知道如何做到这一点

4

3 回答 3

22

在 C 中初始化数组有两种方法:

  • 堆栈上(它将为您处理内存,因为它会在您的函数结束时被清理)
  • 堆中(这将需要您自己处理分配和释放)。

如果你想使用堆栈,你可以像这样初始化你的数组......

#define ARRAY_LENGTH 10
void *ptr;
void *arr[ARRAY_LENGTH];
for (int i = 0; i < ARRAY_LENGTH; i++) {
    arr[i] = ptr;
}

您可以类似地在堆中定义您的数组,如下所示...

#define ARRAY_LENGTH 10
void *ptr;
void **arr = malloc(sizeof(void *) * ARRAY_LENGTH);
for (int i = 0; i < ARRAY_LENGTH; i++) {
    arr[i] = ptr;
}
free(arr);

重要的是要记住一个数组(除了在堆栈中分配的数组,它具有一些附加属性,例如长度)本质上只是一个指向第一个元素的指针,并且操作arr[i]与移动i*sizeof相同(elem)字节远离第一个元素,并在那里访问内存。如果您想获得指向数组中第i个索引的指针,那么您可以使用诸如...

void *indexPtr = arr + i;

或者

void *indexPtr = &( arr[i] );

以这种方式, void*的数组将是void **类型,因为该变量是指向数组第一个成员的指针,它是一个指针。这可能有点令人困惑,但请始终牢记数组元素的类型,并创建指向它们的指针。因此,如果数组是 int 类型,那么数组将是int类型int[],但如果要存储指向整数的指针,则可以使用这两种形式中的任何一种初始化int *类型的数组...

int **arr = malloc(sizeof(int *) * ARRAY_LENGTH);
int *arr[ARRAY_LENGTH];

另请注意,您正在存储指针,因此如果您运行代码...

int *arr[4];
for (int i = 0; i < ARRAY_LENGTH; i++) {
    arr[i] = &i;
}

虽然看起来数组中指向的值如下 - [0, 1, 2, 3],但实际上它是 [4, 4, 4, 4],因为您实际拥有的是一个指针数组,所有指针都指向函数中的变量i,因此无论何时更改它,数组中指向的值都将全部更改。
我希望这有帮助

于 2013-04-20T21:45:37.463 回答
12

您需要更改此行

void* arr = (void*)malloc(sizeof(void*)*10);

对此

void** arr = malloc(sizeof(void*)*10);
于 2013-04-20T19:06:58.983 回答
2

您不能取消引用 void 指针。这就是 void 指针的全部意义所在。取消引用指针使您可以访问在指针指向的地址处找到的项目。但是,使用 void 指针,您不知道目标对象有多大(它是 1B 字符还是 100B 结构?)。在取消引用之前,您必须将其转换为特定的指针类型。

然后将整数i添加(或减去)到指针定义为将 i-times sizeof(*pointer) 添加到指针的内容。(如果您的指针具有特定类型,您只能告诉 sizeof(*pointer)。带有 void 指针的指针算术没有意义)。

至于 (arr+n)= anyptr;,arr+n 只是一个地址。这不是您可以分配某些东西的值(不是左值)。

于 2013-04-20T19:15:35.490 回答