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