问题创建和释放C动态数组

时间:2015-05-07 16:17:52

标签: c arrays pointers

我正在编写一个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

任何人都知道问题可能是什么?

2 个答案:

答案 0 :(得分:1)

您曾拨打calloc一次和malloc一次,但之后您正在呼叫free n + 1次(当然,您正在释放相同的值,{{1} } arr[1]次)。每个nfree应该只有一个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 / freefree(*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_lastprintf("- %d %d %d - ", positions_last[0][1], positions_last[1][1], positions_last[2][1]); 点被释放,那么就是内存无效。访问它会激发UB,因为这样做:

{{1}}

获得的经验:在C语言中,不能通过简单的赋值复制数组