在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的所有指针数组,所以每当你更改
i时,数组中指向的值都会被更改。
希望这可以帮到你。
void *
强制转换成void *
?无论如何,你都不应该进行这样的强制转换。(参见:https://dev59.com/dHRB5IYBdhLWcg3wgHWr) - user529758*(arr+i)
空指针解引用。 - BLUEPIXY