realloc
可能返回相同的输入地址或不同的地址。如果它返回一个不同的地址,那么它将在内部解除分配/释放输入内存并将该内容移动到另一个位置并返回该新地址。
请考虑以下情况。
new_ptr = realloc (2000, 10000) // Lets assume the input address is 2000
// Lets assume the new_ptr address is 3000
因此,内部realloc
将释放指针指向2000的内存并将这些数据移动到新位置3000并返回3000地址。
现在地址2000指向无效。因此,realloc
API未将其分配为NULL。
现在,将该无效地址传递给realloc函数。实时可能存在realloc可能获得无效输入地址的更改。
new_ptr = realloc(2000, 10000)
此2000地址无效,因为它已被之前的realloc
释放。现在程序崩溃了。
我可以通过以下方式解决此问题吗?
if (new_ptr != old_ptr ) {
old_ptr = NULL;
}
由于old_ptr无效。我将它分配给NULL。 请确认我的更正。
答案 0 :(得分:5)
想想你的第一句话:
realloc
可能会返回相同的输入地址或不同的地址。
这意味着您只需使用返回值作为新指针,不必知道它是否与您之前的指针不同。如果不同,realloc()
已经处理过,为您释放上一个块。
但有一个例外:如果分配失败,realloc()
可能会返回0
/ NULL
。 仅在这种情况下,旧指针仍然有效。因此,正确使用realloc()
的常用习惯是这样的:
T *x = malloc(x_size);
// check x for NULL
// [...]
T *tmp = realloc(x, new_size);
if (!tmp)
{
free(x);
// handle error, in many cases just exit(1) or similar
}
x = tmp; // use the new pointer, don't care whether it's the same
请注意,在成功对x
的调用未定义后,使用realloc()
(来自我上面的示例),根据C标准,x
无效通话结束后。这并没有告诉你任何有关x
的实际价值的信息。它只是告诉你" 不要使用它,否则你的程序可能会任何东西 "。
此自我引用可能有助于您了解未定义的行为的含义:
中未定义的行为
C
C是一种非常低级的语言,其结果如下:
没有什么能阻止你做一些完全错误的事情。
许多语言,尤其是某些托管环境的语言,例如
Java
或者C#
当你做不允许的事情时,实际上会阻止你,比方说, 访问不存在的数组元素。C
没有。只要你的 程序语法正确,编译器不会抱怨。如果你这样做 在你的程序中被禁止的东西,C
只是调用你的行为 程序未定义。这正式允许在运行时发生任何事情 该程序。通常,结果将是崩溃或只是输出"垃圾" 值,如上所示。但如果你真的不走运,那么你的计划就会出现 正常工作直到它得到一些稍微不同的输入,并由此 时间,你将很难找到你的计划的确切位置 未定义。因此,一定要避免未定义的行为!。另外,未定义的行为也会导致安全漏洞。这个 在实践中已经发生了很多。
答案 1 :(得分:0)
如果成功,Realloc将释放旧内存块。 注意:如果它可以附加在相同的内存块中,它将自己附加在那里。如果它无法追加,它将创建一个新的内存块并释放旧内存块。
如果你有任何循环逻辑,或者你在realloc完成后使用的指针指向函数内的旧内存块。然后就会崩溃。 如果旧指针只是做realloc而不是不需要。因为你创建的本地指针和它的作用域将仅限于该函数。每次调用函数时它都是新的指针变量。