C语言 空数组指针

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16124045/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:06:45  来源:igfitidea点击:

Pointer of void array

carrayspointersvoid-pointers

提问by 0xDEADBEEF

I have an array of void-Pointers and want to access the elements (inititialize them), but it do not work:

我有一个空指针数组,想访问这些元素(初始化它们),但它不起作用:

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 guess, the reason why this won′t work is that on the left side is the result of element i. But i don′t have an idea how to do this

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

回答by Joe Delgado

There are two ways to initialize arrays in C:

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

  • On the stack(which will handle memory for you since it will be cleaned up when your function ends)
  • In the heap(which will require you to handle allocation and freeing on your own).
  • 堆栈上(它将为您处理内存,因为它会在您的函数结束时被清理)
  • 堆中(这将需要您自己处理分配和释放)。

If you would like to use the stack, you could initialize your array like this...

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

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

You can similarly define your array in the heap as follows...

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

#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);

It is important to remember that an array (besides arrays assigned in the stack, which have some additional attributes such as length) is essentially just a pointer to the first element, and the operation arr[i]is the same as moving i*sizeof(elem)bytes away from the first element, and accessing the memory there. If you would like to get a pointer to the ith index in the array, then you would use notations such as...

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

void *indexPtr = arr + i;

or

或者

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

In this fashion, an array of void*'s would be of type void **, since the variable is a pointer to the first member of the array, which is a pointer. This can be a bit confusing, but just always try to keep in mind what type the elements of the array are, and creating a pointer to them. So if the array is of type int, then the array would be of type int or int[], but if you are storing pointers to integers, you would initialize an array of type int *in either of these two forms...

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

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

Also note that you are storing pointers, so if you run the code...

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

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

Although it may seem to be that the values pointed to in the array would be as follows- [0, 1, 2, 3], but in reality it would be [4, 4, 4, 4], since what you actually have is an array of pointers all pointing to the variable iin your function, so whenever you change that, the values pointed to in the array will all be changed.
I hope this helped

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

回答by Alexey Frunze

You need to change this line

你需要改变这一行

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

to this

对此

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

回答by PSkocik

You can't dereference a void pointer. That's the whole point of void pointers. Dereferencing a pointer provides you with access to the item that's found at the address the pointer points to. With a void pointer, however, you don't know how large the target object is (is it a 1B character or a 100B struct?). You have to cast it to a specific pointer type before dereferencing it.

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

Adding (or subtracting) an integer ito a pointer is then defined as adding i-times sizeof(*pointer) to the pointer's content. (You can only tell sizeof(*pointer) if your pointer has a specific type. Pointer arithmetic with void pointers makes no sense).

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

As for (arr+n)= anyptr;, arr+n is just an address. It's not a value you can assign something to (not an lvalue).

至于 (arr+n)= anyptr; , arr+n 只是一个地址。这不是一个可以赋值的值(不是左值)。