假设我初始化了一个包含 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 的数组,您必须重新分配。
但是如果你需要这样做,也许数组不是你应该使用的数据结构:链表似乎是更好的选择。