我正在编写一个C程序,它涉及在更改大小和条目的函数之间传递2D数组。我决定使用带有指针的动态数组。
每当我释放指向数组的指针时,我发现我擦除了其他数组中的值。我可以成功更改指针指向的数组。我相信这是我释放指针或声明它们的方式的问题。下面是我用来创建和释放指向我的数组的指针的代码。
int** create_array(int m, int n)
{
int i;
int* values = calloc(m * n, sizeof(int));
int** rows = malloc(n * sizeof(int*));
for(i = 0; i < n; i++) {
rows[i] = values + (i * m);
}
return rows;
}
void destroy_array(int** arr)
{
free(arr[0]);
free(arr);
}
用于创建和释放指针的旧代码
int** create_array(int m, int n)
{
int i;
int* values = calloc(m * n, sizeof(int));
int** rows = malloc(n * sizeof(int*));
for(i = 0; i < n; i++) {
rows[i] = values + (i * m * sizeof(int));
}
return rows;
}
void destroy_array(int** arr, int m, int n)
{
int i;
for(i = 0; i < n; i++) {
free(arr[i]);
}
free(arr);
}
在我销毁指向数组的指针并尝试从另一个数组中读取值之后,我的程序会出现段错误。下面是我销毁指向这些数组的指针的代码。 position_last和position都是我在此之前可以正确读取的数组。
positions_last = positions;
printf("- %d %d %d - ", positions_last[0][1], positions_last[1][1], positions_last[2][1]);
fflush(stdout); // this prints fine
destroy_array(positions);
printf("- %d %d %d - ", positions_last[0][1], positions_last[1][1], positions_last[2][1]);
fflush(stdout); // this does not print, I get a segfault at this point
我刚做了一个基本测试,表明问题在于我目前创建或销毁数组的代码(据我所知)。
int** positions2 = create_array(10, 3);
int** positions3 = create_array(10, 3);
printf("%d %d %d", positions3[0][1], positions3[1][1], positions3[2][1]);
fflush(stdout); // This line prints fine
positions3 = positions2;
destroy_array(positions2);
printf("%d %d %d", positions3[0][1], positions3[1][1], positions3[2][1]);
fflush(stdout); // This line triggers a segfault
任何人都知道问题可能是什么?
答案 0 :(得分:1)
您曾拨打calloc
一次和malloc
一次,但之后您正在呼叫free
n + 1次(当然,您正在释放相同的值,{{1} } arr[1]
次)。每个n
或free
应该只有一个malloc
。
calloc
答案 1 :(得分:0)
这一行
rows[i] = values + (i * m * sizeof(int));
应该是
rows[i] = values + (i * m);
这背后的原因是values
是一个类型指针,即指向int
。向1
添加1 * sizeof (int)
会使其增加1
。您的代码假定它仅会增加free()
。
这是基本的指针算术:http://cslibrary.stanford.edu/104/; - )
因此,即使在第一次调用malloc
之前,您也遇到了未定义的行为。
calloc
/ free
和free(*arr); /* Free what had been allocated to "values". */
free(arr); /* Free what had been allocated to "rows". */
也遵循以下模式:
一次分配 - &gt;一次解放
所以释放可能看起来像这样:
positions_last = positions;
zindorsky &#39; answer指出,您展示的代码有不同的含义。
关于你的编辑:
此
positions
不会复制数组及其元素,而只是复制数组1st成员的引用。因此,如果您释放positions_last
也printf("- %d %d %d - ", positions_last[0][1], positions_last[1][1], positions_last[2][1]);
点被释放,那么就是内存无效。访问它会激发UB,因为这样做:
{{1}}
获得的经验:在C语言中,不能通过简单的赋值复制数组