【发布时间】:2014-07-02 01:36:05
【问题描述】:
我无法减小动态创建的数组的大小。这是我的main 函数的样子:
int main(void) {
// Intialize big array
int * a = (int *)malloc(10*sizeof(int));
assert(a);
// Fill it with squares
for (int i = 0; i < 10; ++i)
a[i] = i*i;
// Expected to print 64
printf("%d\n", a[8]);
// Shrink the big array
int * b = (int *)realloc(a, 5*sizeof(int));
assert(b);
// Expected to cause SEGFAULT
printf("%d\n", b[8]);
return 0;
}
除了printf("%d\n", b[8]); 行之外,一切正常,因为它打印64,但没有像我预期的那样导致 SEGFAULT 错误。为什么?
我想我遗漏了一些简单的东西,因为我已经看到很多与使用realloc 缩小内存有关的 SO 问题,但他们都说这是可能的。
我正在使用带有 GCC 4.8.2 的 Ubuntu 14.04 并使用 -std=c99 选项对其进行编译。
【问题讨论】:
-
最近几天有人问过这个问题,或者几乎相同的问题——但我无法立即找到它。尽管
realloc()将内存返回到其内部可用内存池,并且任何对其进行读取或写入的尝试都会导致未定义的行为,但它通常不会取消映射内存,因此访问它通常不会直接导致崩溃——但是从释放的内存中读取是非常糟糕的做法,而写入释放的内存则更糟糕。 -
{Rewrite] 不确定建议的副本。提议的副本与
realloc()或malloc()无关。目前,我没有一个好的副本可以指出,但我还没有进行彻底的搜索。我怀疑我记得的“接近重复”已被其 OP 删除。总的来说,让这个保持打开状态。 -
是的,这个问题和建议的副本都是关于在数组边界之外读取和写入数据 - 在这种情况下是动态分配的,在另一个情况下是正常的(全局变量)。在这个程度上,它们是重复的。但我认为,在分配空间缩小之前,负索引与访问合法内容的重点有所不同。我不会对重复的闭包提出异议,但我更愿意找到一个更明确地解决动态分配的内存和收缩的重复。
标签: c memory malloc realloc shrink