如何在 C 中释放 malloc'd 数组的最后一个元素



假设我初始化了一个包含 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 是个好主意吗?

realloc()可以更改分配的内存块的大小,这将为您完成这项工作。 请注意,这不能用于"释放"数组的任意元素,而只能用于末尾的一个元素。

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

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

如果您想更改分配内存的大小,请按照 Scott 所说的进行操作并realloc块 - 但这是一种处理堆内存的昂贵方式。

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

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

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

顺便说一句,请注意,当你说

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

错了,你正在调用未定义的行为,以及这个 SO 答案所解释的。

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

要在数组内移动元素,可以使用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

如果你正在做一个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 的数组,您必须重新分配。

但是如果你需要这样做,也许数组不是你应该使用的数据结构:链表似乎是更好的选择。

相关内容

  • 没有找到相关文章