当您释放内存时,指向该内存的指针会发生什么?它们会立即失效吗?如果它们后来再次生效会怎样?
当然,指针变为无效然后再次变为“有效”的通常情况是其他对象被分配到恰好是之前使用的内存中,如果您使用指针访问内存,那显然是未定义的行为。悬空指针内存几乎覆盖了第 1 课。
但是,如果内存对于相同的分配再次变得有效怎么办?只有一种标准方式可以做到这一点:realloc()
. 如果您有一个指向malloc()
offset 处的 'd 内存块中某处的指针> 1
,然后使用realloc()
将块缩小到小于您的偏移量,那么您的指针显然会变得无效。如果您再次使用realloc()
将块重新增长到至少覆盖悬空指针指向的对象类型,并且在两种情况下都没有realloc()
移动内存块,那么悬空指针是否再次有效?
这是一个极端情况,我真的不知道如何解释 C 或 C++ 标准来弄清楚。下面是一个显示它的程序。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
static const char s_message[] = "hello there";
static const char s_kitty[] = "kitty";
char *string = malloc(sizeof(s_message));
if (!string)
{
fprintf(stderr, "malloc failed\n");
return 1;
}
memcpy(string, s_message, sizeof(s_message));
printf("%p %s\n", string, string);
char *overwrite = string + 6;
*overwrite = '\0';
printf("%p %s\n", string, string);
string[4] = '\0';
char *new_string = realloc(string, 5);
if (new_string != string)
{
fprintf(stderr, "realloc #1 failed or moved the string\n");
free(new_string ? new_string : string);
return 1;
}
string = new_string;
printf("%p %s\n", string, string);
new_string = realloc(string, 6 + sizeof(s_kitty));
if (new_string != string)
{
fprintf(stderr, "realloc #2 failed or moved the string\n");
free(new_string ? new_string : string);
return 1;
}
// Is this defined behavior, even though at one point,
// "overwrite" was a dangling pointer?
memcpy(overwrite, s_kitty, sizeof(s_kitty));
string[4] = s_message[4];
printf("%p %s\n", string, string);
free(string);
return 0;
}