T.G*_*all 5 c malloc pointers memory-management segmentation-fault
我正在搞乱c我在指针使用和语法区域有一些打嗝.
下面,我(尝试)创建一个指向整数数组的指针数组,然后将每个指针指向一个通过malloc()创建的数组.
创建数组后,然后循环遍历每个单元格,分配一个值.
现在,所有这些似乎都在起作用,但是当使用free()来取回内存时,程序崩溃了.
我注意到如果我在malloc()数组内存然后立即调用它们上的free(),程序执行没有问题.然而,当我malloc(),赋值和THEN调用free()时,将发生崩溃.(分段故障).
下面是有效的代码,malloc()然后立即free()ing
int (*ptrArr[5])[5];
for(int i=0; i<5; i++)
ptrArr[i] = malloc(sizeof(int) * 5);
for(int i=0; i<5; i++)
printf("ptrArr[%d][%x]->[%x]\n", i, &ptrArr[i], &*ptrArr[i]);
printf("\n");
for(int i=0; i<5; i++){
for(int j=0; j<5; j++){
printf("[%x](%2d) | ", &*ptrArr[i][j], *ptrArr[i][j]);
}
printf("\n");
}
for(int i=4; i>=0; i--)
free(ptrArr[i]);
Run Code Online (Sandbox Code Playgroud)
上面按照我的预期执行,但是当我为单元格赋值然后尝试自由调用时,会生成一个分段错误:
int (*ptrArr[5])[5];
for(int i=0; i<5; i++)
ptrArr[i] = malloc(sizeof(int) * 5);
for(int i=0; i<5; i++)
printf("ptrArr[%d][%x]->[%x]\n", i, &ptrArr[i], &*ptrArr[i]);
printf("\n");
for(int i=0; i<5; i++){
for(int j=0; j<5; j++){
printf("[%x](%2d) | ", &*ptrArr[i][j], *ptrArr[i][j]);
}
printf("\n");
}
int loop = 5;
for(int i=0; i<5; i++){
for(int j=0; j<5; j++){
*ptrArr[i][j] = (loop + (i*j));
++loop;
}
}
printf("\n");
for(int i=0; i<5; i++){
for(int j=0; j<5; j++){
printf("[%x](%2d) | ", &*ptrArr[i][j], *ptrArr[i][j]);
}
printf("\n");
}
for(int i=4; i>=0; i--)
{
printf("Freeing ptrArr[%x]\n", i);
free(ptrArr[i]);
}
Run Code Online (Sandbox Code Playgroud)
我想我要么误解了
int (*ptrArr[5])[5];
Run Code Online (Sandbox Code Playgroud)
声明,我打算是一个5个指针的数组,每个指针指向一个整数数组,或者我没有正确地为单元格赋值,而是破坏导致free()失败的内存.
任何帮助将不胜感激,我希望这个问题清楚简洁.
谢谢.
我解决此类问题的方法是打印出sizeof
各种嫌疑人,如下所示
int (*test[5])[5];
printf( "%zu ", sizeof(test) );
printf( "%zu ", sizeof(test[0]) );
printf( "%zu\n", sizeof(test[0][0]) );
Run Code Online (Sandbox Code Playgroud)
结果是40 8 20
。(请注意,在我的机器上,anint
是 4 个字节,指针是 8 个字节。)
这告诉我这test
是一个由 5 个指针组成的数组。从逻辑上讲,这test[0]
是一个单一的指针。但有趣的是,这test[0][0]
是一个由 5 个整数组成的数组。
如果我添加以下代码行
printf( "%zu\n", sizeof(test[0][0][0]) );
Run Code Online (Sandbox Code Playgroud)
输出是 4,即test[0][0][0]
是一个int
。由此我们得出结论,该声明int (*test[5])[5]
正在声明一个三维数组,这不是您想要的。
所以让我们尝试一个更简单的声明,就像这样
int (*test)[5];
printf( "%zu ", sizeof(test) );
printf( "%zu ", sizeof(test[0]) );
printf( "%zu\n", sizeof(test[0][0]) );
Run Code Online (Sandbox Code Playgroud)
输出是8 20 4
,也就是说,它test
是一个指针,test[0]
是一个 5 个整数的数组,并且test[0][0]
是一个int
。我们得出结论,int (*test)[5]
声明了一个二维数组。
下一个问题是我们如何为数组分配内存。如果我们这样做
test = malloc( 5 * sizeof(int) );
Run Code Online (Sandbox Code Playgroud)
那么我们有一个 1 行 5 列的数组,基本上是一个一维数组。
要获得包含行的二维数组N
,我们需要
test = malloc( N * 5 * sizeof(int) );
Run Code Online (Sandbox Code Playgroud)
然后我们可以像这样填充、打印和释放数组
int N = 5;
for ( int row = 0; row < N; row++ )
for ( int col = 0; col < 5; col++ )
test[row][col] = (row+5)*10 + col;
for ( int row = 0; row < N; row++ )
{
for ( int col = 0; col < 5; col++ )
printf( "%2d ", test[row][col] );
printf( "\n" );
}
free( test );
Run Code Online (Sandbox Code Playgroud)