如何释放 C 中 malloc 数组的最后一个元素?
How to free the final element of a malloc'd array in C?
假设我像这样初始化一个包含 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()
可以更改分配的内存块的大小,这将为您完成这项工作。请注意,这不能用于 "free" 数组的任意元素,但只能用于末尾的一个。
这样做的好主意取决于许多因素,none 您已经提供了这些因素。
关于数组的最后一个元素,你肯定可以使用 realloc
顺便说一句,请注意当你说
数组如下所示:{1, 2, 3, 4, #},其中 # 是一些垃圾值。
你错了,你正在调用未定义的行为,正如 this SO answer 所解释的那样。
所以左移值的循环不用做Q[4] = Q[5];
当你执行 Q++ 时,数组没有改变,它仍然包含五个值 0、1、2、3、4,只是 Q 指向数组中的第二个元素。
如果您想更改已分配内存的大小,请按照 Scott 所说的那样进行 realloc
块 - 但这是一种处理堆内存的昂贵方法。
如果您只想跟踪数组中元素的数量,让 Q 保持指向第一个元素,并有一个大小变量指示有多少个整数。
或者使用另一种数据结构来保存整数,例如整数链表,然后您可以更轻松地添加和删除整数。
要在数组内移动元素,可以使用 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 的数组,您必须重新分配。
但是如果你需要这样做,也许数组不是你应该使用的数据结构:链表似乎是更好的选择。
假设我像这样初始化一个包含 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()
可以更改分配的内存块的大小,这将为您完成这项工作。请注意,这不能用于 "free" 数组的任意元素,但只能用于末尾的一个。
这样做的好主意取决于许多因素,none 您已经提供了这些因素。
关于数组的最后一个元素,你肯定可以使用 realloc
顺便说一句,请注意当你说
数组如下所示:{1, 2, 3, 4, #},其中 # 是一些垃圾值。
你错了,你正在调用未定义的行为,正如 this SO answer 所解释的那样。
所以左移值的循环不用做Q[4] = Q[5];
当你执行 Q++ 时,数组没有改变,它仍然包含五个值 0、1、2、3、4,只是 Q 指向数组中的第二个元素。
如果您想更改已分配内存的大小,请按照 Scott 所说的那样进行 realloc
块 - 但这是一种处理堆内存的昂贵方法。
如果您只想跟踪数组中元素的数量,让 Q 保持指向第一个元素,并有一个大小变量指示有多少个整数。
或者使用另一种数据结构来保存整数,例如整数链表,然后您可以更轻松地添加和删除整数。
要在数组内移动元素,可以使用 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 的数组,您必须重新分配。
但是如果你需要这样做,也许数组不是你应该使用的数据结构:链表似乎是更好的选择。