[英]Why isn't realloc shrinking the array?
我在减小动态创建数组的大小方面遇到了麻烦。 这是我的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问题,但是所有人都说这是可能的。
我正在将Ubuntu 14.04和GCC 4.8.2一起使用,并使用-std=c99
选项进行编译。
第二个printf
调用中的b[8]
访问未分配的内存,并调用未定义的行为。 这就是基本上未定义的行为的意思。 结果是不可预测的。 它似乎工作正常,但下次可能会崩溃。 这里没有其他要考虑的事情-
malloc
可能无法分配内存,因此使用assert
宏检查其返回值是错误的。 assert
应该用于调试不可能或错误的代码,例如访问数组之外的代码。
您不应该转换malloc
的结果。 我要转换malloc的结果吗?
realloc
可能无法重新分配像malloc
这样的内存块。 失败时,它返回NULL
,并使较旧的块保持不变。 这意味着您将失去对旧内存块的处理,从而导致其泄漏。 您应该在调用realloc
之前将指向较旧块的指针存储在变量中。
您正在访问未分配的空间。 那是不确定的行为。 在最坏的情况下(如现在),它仍然有效。 Segfault不保证会发生。
Realloc只会标记可用于将来的malloc操作的剩余缓冲区。 是UB,如果该缓冲区上没有发生malloc,您仍然可以访问该缓冲区,这就是您所遇到的情况。 您只是很幸运,没有在访问未分配的内存时遇到段错误。
它是未定义的,执行此操作时它是否可能崩溃,取决于您访问的内存是否属于您的进程:
int i;
int a[5];
for(i=0;i<10;i++)
printf("%d\n", a[i]);
您必须自己检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.