如何释放C中malloc数组的最终元素?

时间:2016-05-25 12:33:08

标签: c arrays malloc free

假设我初始化一个包含5个整数元素的数组:

int *Q = malloc(sizeof(int) * 5);

for (int i = 0; i < 5; i++) {
    Q[i] = i;
}

数组看起来像:{0,1,2,3,4}。 现在如果我把所有东西都移动到1个位置:

Q++;

数组看起来像:{1,2,3,4,#},其中#是垃圾值。

有没有办法释放最终元素,因此它没有存储在数组中?

我试过了:

free(Q[4]);

但我知道这不会起作用,因为free()只能操作为Q分配的整个内存块。

有没有更好的方法来改变一切?生成的数组应如下所示:{1,2,3,4}。

每班次后重新分配()Q会不是一个好主意?

5 个答案:

答案 0 :(得分:5)

realloc()可以改变分配的内存块的大小,这将为您完成工作。请注意,这不能用于“释放”数组的任意元素,但最后只能使用一个元素。

这样做的好处取决于许多因素,而这些因素都没有提供。

答案 1 :(得分:2)

当你做Q ++时,数组没有改变,它仍然包含五个值0,1,2,3,4只是Q指向数组中的第二个元素。

如果你想改变已分配内存的大小,那么就像Scott所说的那样和realloc块一样 - 但这是一种处理堆内存的昂贵方法。

如果你只想跟踪数组中元素的数量,让Q保持指向第一个元素,并有一个大小变量指示有多少整数。

或者使用另一种数据结构来保存整数,例如一个链接的整数列表,然后您可以更容易地添加和删除整数。

答案 2 :(得分:1)

关于数组的最后元素,你肯定可以使用realloc

BTW请注意,当你说

数组看起来像:{1,2,3,4,#},其中#是垃圾值。

你错了,你正在调用未定义的行为,正如this SO answer解释的那样。

所以左移位值的循环不能Q[4] = Q[5];

答案 3 :(得分:1)

要在数组内部移动元素,可以使用memmove()

#include <stdio.h>
#include <string.h>

int main(void)
{
  int d_init[] = {0, 1, 2, 3, 4};

  size_t s = sizeof d_init/sizeof *d_init;
  int d[s];

  /* Fill d */
  memcpy(d, d_init, s * sizeof *d);

  for (size_t i = 0; i < s; ++i)
    printf("%d ", d[i]);
  puts("\n");

  /* shift one to the left */
  memmove(d, d + 1, (s - 1) * sizeof *d);

  for (size_t i = 0; i < s; ++i)
    printf("%d ", d[i]);
  puts("\n");


  /* shift two to the right */
  memmove(d + 2, d, (s - 2) * sizeof *d);  

  for (size_t i = 0; i < s; ++i)
    printf("%d ", d[i]);
  puts("\n");
}

上面的代码段会打印出来:

0 1 2 3 4
1 2 3 4 4
1 2 1 2 3

答案 4 :(得分:0)

如果你正在做Q++你没有移动数组的元素,你的数组只是指向第二个元素(索引1)。因此,Q [4]正在读取不属于数组的东西:C允许你这么做(在大多数情况下),但这是一个错误。

要移动元素,你应该做

for (int i=0; i<4; i++)
    Q[i] = Q[i+1];

或(更聪明)

memmove(Q, Q+1, 4*sizeof(int));

但实际上,要有一个4号数组,你必须重新分配。

但是如果您需要这样做,可能数组不是您应该使用的数据结构:链接列表似乎是更好的选择。