访问作为 void 指针段错误传递的 int 数组
Accessing an int array passed as void pointer segfaults
我正在玩指针,偶然发现了这个问题。就像在这个 中一样,我想要函数 foo 的通用方法签名,因此我选择 void * input
作为参数。出于测试原因,我将 void 指针转换为 int **
指针,以便像二维数组一样使用它。
#include <stdio.h>
#include <stdlib.h>
void * foo(void *input, size_t mySize)
{
for (size_t i = 0; i < mySize; ++i)
{
for (size_t j = 0; j < mySize; ++j)
{
((int **)input)[i*mySize][j] = 10*i+j;
}
}
return input;
}
int main(int argc, char const *argv[])
{
size_t const mySize = 10;
void * myMemory, * testPtr;
myMemory = malloc(mySize * mySize * sizeof(int));
testPtr = foo(myMemory, mySize);
free(testPtr);
return 0;
}
现在我认为使用 []
运算符与向指针添加一个 int 相同,例如((int **)input[i][j]
与 `((int **)input)+i+j
相同
但是在 foo
段错误中访问输入数组并使用 gdb 显示
(gdb) p ((int **)input)[i][j]
Cannot access memory at address 0x0
(gdb) p ((int **)input)+i+j
= (int **) 0x405260
所以显然是有区别的。因此我很困惑。
您分配了一个包含 mySize*mySize 元素的一维数组。
int** 是指向int的指针数组,你要的是
int **array2d;
int *p;
array2D = malloc(ROWS * sizeof(int*) + ROWS * COLUMNS * sizeof(int));
p = (int*) &array2d[ROWS];
for (size_t i = 0; i < ROWS; ++i)
array2d[i] = &p[i * COLUMNS];
现在 array2d[行][列] 可以工作了。
或者,如前所述,使用一维数组并使用数组[行 * 列 + 列] 公式。
虽然数组和指针很相似,但它们并不相同。
数组——单维或多维——描述了一块连续的内存,包含特定的数据类型。例如int arr [10]
声明arr
在内存中连续10个int
。 int multi_arr[5][10]
将 multi_arr
声明为内存中 10 个连续 int
的 5 个数组。
此外,名字arr
就是这个数组的基地址,把它传给函数就和传&arr[0]
.
一样了
但相似之处仅此而已。多维数组不能(技术上)转换为指向指针的指针然后再返回。
如果上面的 arr
指向一个 int
的块,那么解除对 int ** ptr
的第一个维度的引用将导致您指向一个指向 int
的指针块。取消引用 that 不会像多维数组那样让您更深入地了解该块,而是它可以指向任何地方。
我正在玩指针,偶然发现了这个问题。就像在这个 void * input
作为参数。出于测试原因,我将 void 指针转换为 int **
指针,以便像二维数组一样使用它。
#include <stdio.h>
#include <stdlib.h>
void * foo(void *input, size_t mySize)
{
for (size_t i = 0; i < mySize; ++i)
{
for (size_t j = 0; j < mySize; ++j)
{
((int **)input)[i*mySize][j] = 10*i+j;
}
}
return input;
}
int main(int argc, char const *argv[])
{
size_t const mySize = 10;
void * myMemory, * testPtr;
myMemory = malloc(mySize * mySize * sizeof(int));
testPtr = foo(myMemory, mySize);
free(testPtr);
return 0;
}
现在我认为使用 []
运算符与向指针添加一个 int 相同,例如((int **)input[i][j]
与 `((int **)input)+i+j
但是在 foo
段错误中访问输入数组并使用 gdb 显示
(gdb) p ((int **)input)[i][j]
Cannot access memory at address 0x0
(gdb) p ((int **)input)+i+j
= (int **) 0x405260
所以显然是有区别的。因此我很困惑。
您分配了一个包含 mySize*mySize 元素的一维数组。 int** 是指向int的指针数组,你要的是
int **array2d;
int *p;
array2D = malloc(ROWS * sizeof(int*) + ROWS * COLUMNS * sizeof(int));
p = (int*) &array2d[ROWS];
for (size_t i = 0; i < ROWS; ++i)
array2d[i] = &p[i * COLUMNS];
现在 array2d[行][列] 可以工作了。
或者,如前所述,使用一维数组并使用数组[行 * 列 + 列] 公式。
虽然数组和指针很相似,但它们并不相同。
数组——单维或多维——描述了一块连续的内存,包含特定的数据类型。例如int arr [10]
声明arr
在内存中连续10个int
。 int multi_arr[5][10]
将 multi_arr
声明为内存中 10 个连续 int
的 5 个数组。
此外,名字arr
就是这个数组的基地址,把它传给函数就和传&arr[0]
.
但相似之处仅此而已。多维数组不能(技术上)转换为指向指针的指针然后再返回。
如果上面的 arr
指向一个 int
的块,那么解除对 int ** ptr
的第一个维度的引用将导致您指向一个指向 int
的指针块。取消引用 that 不会像多维数组那样让您更深入地了解该块,而是它可以指向任何地方。