当 2 个指针指向同一区域并且其中 1 个被释放时会发生什么?
What happens when 2 pointers point to same area and 1 of them is freed?
char *oldPointer, *newPointer;
oldPointer = (char*)malloc(1000);
newPointer = (char*)realloc(oldPointer, 2000)
现在可以oldPointer
使用吗?
现在会发生什么?
oldPointer = newPointer;
如果 free(newPointer)
会怎样?
在检查 realloc() 之后发生的事情之前,您不能安全地使用任何一个指针。
可能性一:
realloc失败,newpointer为NULL不能使用,oldPointer可以。
可能性2:
realloc 成功 and not 必须重新定位旧的 malloc 内存。在这种情况下,您可以使用两个指针。 (他们拥有相同的地址值)
可能性3:
重新分配成功但必须在不同的地方分配内存并释放旧的内存块。现在 oldPointer 仍将指向旧的内存地址,该地址不再有效。这称为悬挂指针。
但是,newPointer 是有效的,可以使用。
Can oldPointer be used now?
当你说 "be used" 时,我假设你的意思是 "can the pointer be dereferenced"。换句话说 - 可以做 *oldPointer
或 oldPointer[200]
或类似的事情吗?
答案是:这取决于newPointer
的值。
除非发生分配错误(例如内存不足),否则函数 realloc
将在重新分配后 return 指向内存的指针。如果出现错误realloc
returns NULL.
因此realloc
的正确使用方法是将return值保存在另一个指针中,然后检查是否为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;
}
What happens if free(newPointer)?
如果 newPointer
指向与 oldPointer
相同的内存,将不再允许取消引用任何指针。示例:
oldPointer = newPointer;
free(newPointer);
oldPointer[9] = something; // Illegal !!
newPointer[9] = something; // Illegal !!
What happens when 2 pointers point to same area and 1 of them is freed?
oldPointer = (char*)malloc(1000);
newPointer = (char*)realloc(oldPointer, 2000)
oldPointer 和 newPointer 可能 不指向同一个区域。这就是 realloc()
所做的。如果内存管理器决定这样做,新指针可能会有所不同(例如,如果旧区域没有足够的 space 来覆盖所需的新区域 space)。假设它们确实指向同一区域会导致未定义的行为(UB - 可能会或可能不会按您预期的那样工作,从而导致调试困难)。
1 of them is freed
之后
oldPointer = (char*)malloc(1000);
newPointer = (char*)realloc(oldPointer, 2000)
您不能在 realloc
之后使用 oldPointer
。只有 newPointer
存在。如果你释放 oldPointer
并且地址改变了,UB(可能崩溃)。如果释放 oldPointer
并且它与 newPointer
的地址相同,这当然与释放 newPointer
相同。
无论如何,规则很简单:在重新分配后不要使用 oldPointer
。除非
oldPointer = malloc(1000);
oldPointer = realloc(oldPointer, 2000);
^^^
你们用的是同一个指针。但不建议,因为如果 realloc
失败,你没有以前分配的地址的痕迹(除非你保存它);这是一个泄漏。
并且不要转换 malloc / realloc。
根据 the standard:
The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.
char *oldPointer, *newPointer;
oldPointer = (char*)malloc(1000);
newPointer = (char*)realloc(oldPointer, 2000)
现在可以oldPointer
使用吗?
现在会发生什么?
oldPointer = newPointer;
如果 free(newPointer)
会怎样?
在检查 realloc() 之后发生的事情之前,您不能安全地使用任何一个指针。
可能性一:
realloc失败,newpointer为NULL不能使用,oldPointer可以。
可能性2:
realloc 成功 and not 必须重新定位旧的 malloc 内存。在这种情况下,您可以使用两个指针。 (他们拥有相同的地址值)
可能性3:
重新分配成功但必须在不同的地方分配内存并释放旧的内存块。现在 oldPointer 仍将指向旧的内存地址,该地址不再有效。这称为悬挂指针。
但是,newPointer 是有效的,可以使用。
Can oldPointer be used now?
当你说 "be used" 时,我假设你的意思是 "can the pointer be dereferenced"。换句话说 - 可以做 *oldPointer
或 oldPointer[200]
或类似的事情吗?
答案是:这取决于newPointer
的值。
除非发生分配错误(例如内存不足),否则函数 realloc
将在重新分配后 return 指向内存的指针。如果出现错误realloc
returns NULL.
因此realloc
的正确使用方法是将return值保存在另一个指针中,然后检查是否为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;
}
What happens if free(newPointer)?
如果 newPointer
指向与 oldPointer
相同的内存,将不再允许取消引用任何指针。示例:
oldPointer = newPointer;
free(newPointer);
oldPointer[9] = something; // Illegal !!
newPointer[9] = something; // Illegal !!
What happens when 2 pointers point to same area and 1 of them is freed?
oldPointer = (char*)malloc(1000);
newPointer = (char*)realloc(oldPointer, 2000)
oldPointer 和 newPointer 可能 不指向同一个区域。这就是 realloc()
所做的。如果内存管理器决定这样做,新指针可能会有所不同(例如,如果旧区域没有足够的 space 来覆盖所需的新区域 space)。假设它们确实指向同一区域会导致未定义的行为(UB - 可能会或可能不会按您预期的那样工作,从而导致调试困难)。
1 of them is freed
之后
oldPointer = (char*)malloc(1000);
newPointer = (char*)realloc(oldPointer, 2000)
您不能在 realloc
之后使用 oldPointer
。只有 newPointer
存在。如果你释放 oldPointer
并且地址改变了,UB(可能崩溃)。如果释放 oldPointer
并且它与 newPointer
的地址相同,这当然与释放 newPointer
相同。
无论如何,规则很简单:在重新分配后不要使用 oldPointer
。除非
oldPointer = malloc(1000);
oldPointer = realloc(oldPointer, 2000);
^^^
你们用的是同一个指针。但不建议,因为如果 realloc
失败,你没有以前分配的地址的痕迹(除非你保存它);这是一个泄漏。
并且不要转换 malloc / realloc。
根据 the standard:
The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.