realloc()悬空指针和未定义的行为

realloc()悬空指针和未定义的行为,c,pointers,undefined-behavior,realloc,dangling-pointer,C,Pointers,Undefined Behavior,Realloc,Dangling Pointer,释放内存时,指向内存的指针会发生什么情况?它们会立即失效吗?如果它们以后再次生效会发生什么 当然,指针失效然后再次变为“有效”的通常情况是其他对象被分配到之前使用过的内存中,如果使用指针访问内存,这显然是未定义的行为。悬空指针内存几乎覆盖了第1课 但是,如果内存对于相同的分配再次变为有效,该怎么办?只有一种标准方法可以实现这一点:realloc()。如果在偏移量>1处有一个指向malloc()'d内存块内某处的指针,则使用realloc()将该块缩小到小于偏移量,显然,指针将无效。如果随后再次使

释放内存时,指向内存的指针会发生什么情况?它们会立即失效吗?如果它们以后再次生效会发生什么

当然,指针失效然后再次变为“有效”的通常情况是其他对象被分配到之前使用过的内存中,如果使用指针访问内存,这显然是未定义的行为。悬空指针内存几乎覆盖了第1课

但是,如果内存对于相同的分配再次变为有效,该怎么办?只有一种标准方法可以实现这一点:
realloc()
。如果在偏移量
>1
处有一个指向
malloc()
'd内存块内某处的指针,则使用
realloc()
将该块缩小到小于偏移量,显然,指针将无效。如果随后再次使用
realloc()
将块重新增长,以至少覆盖悬挂指针指向的对象类型,并且在这两种情况下
realloc()
都没有移动内存块,悬挂指针是否再次有效

这是一个很难理解的C语言或C++标准来解释它。下面是一个显示它的程序

#包括
#包括
#包括
内部主(空)
{
static const char s_message[]=“您好”;
静态常量char s_kitty[]=“kitty”;
char*string=malloc(sizeof(s_消息));
如果(!字符串)
{
fprintf(stderr,“malloc失败\n”);
返回1;
}
memcpy(字符串、s_消息、sizeof(s_消息));
printf(“%p%s\n”,字符串,字符串);
char*overwrite=string+6;
*覆盖='\0';
printf(“%p%s\n”,字符串,字符串);
字符串[4]='\0';
char*new_string=realloc(string,5);
如果(新字符串!=字符串)
{
fprintf(stderr,“realloc#1失败或移动了字符串\n”);
自由(新字符串?新字符串:字符串);
返回1;
}
字符串=新字符串;
printf(“%p%s\n”,字符串,字符串);
新字符串=realloc(字符串,6+sizeof(s_kitty));
如果(新字符串!=字符串)
{
fprintf(stderr,“realloc#2失败或移动了字符串\n”);
自由(新字符串?新字符串:字符串);
返回1;
}
//这就是定义的行为,即使在某一点上,
//“覆盖”是一个悬而未决的指针?
memcpy(覆盖、s_kitty、sizeof(s_kitty));
字符串[4]=s_消息[4];
printf(“%p%s\n”,字符串,字符串);
自由(弦);
返回0;
}

这取决于您对“有效”的定义。你已经很好地描述了情况。如果你想考虑“有效”,那么它是有效的。如果你不想考虑“有效”,那么它是无效的。

< P>这取决于你对“有效”的定义。你已经很好地描述了情况。如果你想考虑“有效”,那么它是有效的。如果你不想认为那是“有效的”,那么它是无效的。 如果随后再次使用realloc()将块增长回至少覆盖悬挂指针指向的对象类型,并且realloc()在任何情况下都没有移动内存块,那么悬挂指针是否再次有效

否。除非
realloc()
返回空指针,否则调用将终止分配对象的生存期,这意味着指向该对象的所有指针都将无效。如果
realloc()
成功,它将返回新对象的地址

当然,它可能正好是旧的地址。在这种情况下,使用指向旧对象的无效指针访问新对象通常在C语言的非优化实现中有效

不过,这仍然是未定义的行为,并且需要积极优化编译器

C语言是不健全的,通常由程序员来维护它的不变量。否则将破坏与编译器的隐式契约,并可能导致生成错误的代码

如果随后再次使用realloc()将块增长回至少覆盖悬挂指针指向的对象类型,并且realloc()在任何情况下都没有移动内存块,那么悬挂指针是否再次有效

否。除非
realloc()
返回空指针,否则调用将终止分配对象的生存期,这意味着指向该对象的所有指针都将无效。如果
realloc()
成功,它将返回新对象的地址

当然,它可能正好是旧的地址。在这种情况下,使用指向旧对象的无效指针访问新对象通常在C语言的非优化实现中有效

不过,这仍然是未定义的行为,并且需要积极优化编译器

C语言是不健全的,通常由程序员来维护它的不变量。否则将破坏与编译器的隐式契约,并可能导致生成错误的代码

释放内存时,指向内存的指针会发生什么情况?它们会立即失效吗

是的,当然。根据C标准第6.2.4节:

对象的生存期是程序执行期间存储被删除的部分 保证为它保留。对象存在,具有恒定地址,并保留 它在整个生命周期中的最后一个存储值。如果在对象的外部引用对象 在生命周期中,行为未定义。指针的值在以下情况下变得不确定: 它指向(或刚刚过去)的对象到达其生命周期的终点

以及第7.22.3.5节:

realloc函数解除分配ptr指向的旧对象,并返回 指向大小由size指定的新对象的指针。新报告的内容 对象应与解除分配前的旧对象相同,直至lesse