我正在编写一个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);
}
我的程序将指针销毁到一个数组后,然后尝试从另一个数组中读取值。以下是我将指针销毁这些阵列的代码。位置_last和位置都是我可以在此之前正确阅读的数组。
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
有人知道问题可能是什么?
您一次调用 calloc
,然后一次调用 malloc
,但随后您正在调用 free
n 1次(当然,您可以释放相同的值,arr[1]
n
次)。每个malloc
或calloc
应该有一个free
。
void destroy_array(int** arr)
{
free(arr[0]);
free(arr);
}
此行
rows[i] = values + (i * m * sizeof(int));
应该是
rows[i] = values + (i * m);
背后的原因是values
是一个打字指针,即指向int
。将1
添加到其上增加了1 * sizeof (int)
。您的代码假定仅将其增加1
。
这是基本的指针算术:http://cslibrary.stanford.edu/104/; - )
因此,您甚至在第一次致电free()
之前就遇到了未定义的行为。
也malloc
/calloc
和free
遵循模式:
一个分配 ->一个释放
因此,释放可能看起来像这样:
free(*arr); /* Free what had been allocated to "values". */
free(arr); /* Free what had been allocated to "rows". */
您显示的代码确实有所不同,如 zindorsky的答案。
关于您的编辑:
这个
positions_last = positions;
不复制数组,其元素,而只是对数组第一成员的引用。因此,如果您也将positions
划分为positions_last
点释放,那就是Invalif内存。访问它会引起UB,就像此行所做的那样:
printf("- %d %d %d - ", positions_last[0][1], positions_last[1][1], positions_last[2][1]);
学习的课程:在C中,一个人不能通过简单的作业复制数组