当输入地址指向无效地址

时间:2017-07-20 06:12:01

标签: c memory-management realloc

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。 请确认我的更正。

2 个答案:

答案 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而不是不需要。因为你创建的本地指针和它的作用域将仅限于该函数。每次调用函数时它都是新的指针变量。