当2个指针指向同一区域并且其中1个指针被释放时会发生什么?

时间:2019-03-30 03:37:38

标签: c malloc realloc

char *oldPointer, *newPointer;

oldPointer = (char*)malloc(1000);
newPointer = (char*)realloc(oldPointer, 2000)

现在可以使用oldPointer吗?

现在会发生什么?

oldPointer = newPointer;

如果free(newPointer)会发生什么?

4 个答案:

答案 0 :(得分:2)

  

当2个指针指向同一区域并且其中1个指针被释放时会发生什么?

oldPointer = (char*)malloc(1000);
newPointer = (char*)realloc(oldPointer, 2000)

oldPointer和newPointer 可能不指向同一区域。 realloc()就是这样做的。如果内存管理器决定这样做,则新指针可能会有所不同(例如,如果旧区域没有足够的空间来覆盖新的所需空间)。假设它们确实指向同一区域,则会引起未定义的行为(UB-可能无法正常工作,导致调试困难)。

  

其中1个已释放

之后

oldPointer = (char*)malloc(1000);
newPointer = (char*)realloc(oldPointer, 2000)

oldPointer之后不能再使用realloc。仅newPointer存在。如果您释放oldPointer并且地址更改了,则UB(可能崩溃)。如果您释放oldPointer,并且地址与newPointer相同,那么这与释放newPointer相同。

无论如何,规则很简单:重新分配后不要使用oldPointer。除非

oldPointer = malloc(1000);
oldPointer = realloc(oldPointer, 2000);
^^^

您使用相同的指针。但不建议您使用realloc失败,因为您没有跟踪先前分配的地址(除非您保存了该地址);这是一个泄漏。

也不要强制malloc / realloc。

答案 1 :(得分:1)

在检查realloc()之后发生的事情之前,您不能安全地使用任何一个指针。

可能性1:

重新分配失败,则newpointer将为NULL,无法使用,但oldPointer可以使用。

可能性2:

重新分配成功不必重新放置旧的malloc存储的内存。在这种情况下,您可以同时使用两个指针。 (它们具有相同的地址值)

可能性3:

重新分配成功,但必须在其他位置分配内存并释放旧的内存块。现在,oldPointer仍将指向旧的内存地址,该地址不再有效。这称为悬空指针。

但是,newPointer有效并且可以使用。

答案 2 :(得分:0)

  

现在可以使用oldPointer吗?

当您说“被使用”时,我假设您的意思是“可以取消引用该指针”。换句话说-做*oldPointeroldPointer[200]或类似的事情是否可以。

答案是:这取决于newPointer的值。

函数realloc将在重新分配后返回指向内存的指针,除非发生分配错误(例如,内存不足)。如果发生错误,realloc返回NULL。

因此,使用realloc的正确方法是将返回值保存在另一个指针中,然后检查NULL。喜欢

oldPointer = (char*)malloc(1000);                // BTW: dont use cast
newPointer = (char*)realloc(oldPointer, 2000);   // BTW: dont use cast
if (newPointer == NULL)
{
    // realloc failed....

    // the value of oldPointer is still valid

    // It is ok to dereference oldPointer, e.g. using oldPointer[10]

    // Here you will normally have some error handling
}
else
{
    // realloc success

    // the value of oldPointer shall be considered invalid.
    // the value of oldPointer may NOT be dereferenced anymore.
    // also notice that you may NOT call free(oldPointer).

    // Normally we save the value of newPointer into oldPointer
    // so that the value of oldPointer becomes valid and usable again
    oldPointer = newPointer;
}
  

免费(newPointer)会发生什么?

如果newPointer指向与oldPointer相同的内存,将不再允许其取消引用任何指针。示例:

oldPointer = newPointer;
free(newPointer);
oldPointer[9] = something;  // Illegal !!
newPointer[9] = something;  // Illegal !!

答案 3 :(得分:0)

根据the standard

  

free函数使ptr指向的空间被释放,即可以用于进一步分配。如果ptr是空指针,则不执行任何操作。否则,如果参数与calloc,malloc或realloc函数先前返回的指针不匹配,或者如果已通过调用free或realloc释放空间,则该行为是不确定的