是否允许编译器回收释放的指针变量? [英] Is the compiler allowed to recycle freed pointer variables?

查看:27
本文介绍了是否允许编译器回收释放的指针变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人声称

realloc 被释放之后,编译器可以自由地将指针变量重用于其他目的,因此您不能保证它具有与之前相同的值之前

a compiler is free to reuse the pointer variable for some other purpose after the realloc being freed, so you have no guarantee that it has the same value as it did before

void *p = malloc(42);
uintptr_t address = (uintptr_t)p;
free(p);

// [...] stuff unrelated to p or address

assert((uintptr_t)p == address);

可能会失败.

C11 附件 J.2 读取

C11 annex J.2 reads

一个指针的值,该指针指向通过调用 free 或使用了 realloc 函数 (7.22.3) [未定义]

The value of a pointer that refers to space deallocated by a call to the free or realloc function is used (7.22.3) [is undefined]

但附件当然不规范.

Annex L.3(规范性的,但可选的)告诉我们,如果

Annex L.3 (which is normative, but optional) tells us that if

一个指针的值,该指针指向通过调用 free 或 realloc 释放的空间使用函数(7.22.3).

The value of a pointer that refers to space deallocated by a call to the free or realloc function is used (7.22.3).

允许结果为严重的未定义行为.

the result is permitted to be critical undefined behaviour.

这证实了这一说法,但我想从标准本身而不是附件中看到适当的引述.

This confirms the claim, but I'd like to see an appropriate quote from the standard proper instead of the annex.

推荐答案

当一个对象到达其生命周期结束时,所有指向它的指针都变得不确定.这同样适用于块范围变量和 malloced 内存.适用的条款是,在 C11 中,6.2.4:2.

Upon an object reaching the end of its lifetime, all pointers to it become indeterminate. This applies to block-scope variables and to malloced memory just the same. The applicable clause is, in C11, 6.2.4:2.

对象的生命周期是程序执行期间保证为其保留存储空间的部分.一个对象存在,有一个常量地址,并在其整个生命周期中保留其最后存储的值.如果对象在其生命周期之外被引用,则行为未定义.当指针指向(或刚刚过去)的对象生命周期结束时,指针的值变得不确定.

The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address, and retains its last-stored value throughout its lifetime. If an object is referred to outside of its lifetime, the behavior is undefined. The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.

将不确定内存用于任何事情,包括表面上无害的比较或算术,是未定义行为(在 C90 中;后来的标准使事情变得非常复杂,但编译器继续将不确定内存的使用视为未定义行为).

Using indeterminate memory for anything, including apparently harmless comparison or arithmetic, is undefined behavior (in C90; later standards complicate the matter terribly but compilers continue to treat usage of indeterminate memory as undefined behavior).

举个例子,下面的程序打印出pq既不同又相同如何?各种编译器的执行结果显示在此处.

As an example, how about the following program printing that p and q are both different and the same? The results of execution with various compilers are shown here.

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main(int argc, char *argv[]) {
  char *p, *q;
  uintptr_t pv, qv;
  {
    char a = 3;
    p = &a;
    pv = (uintptr_t)p;
  }
  {
    char b = 4;
    q = &b;
    qv = (uintptr_t)q;
  }
  printf("Roses are red,
Violets are blue,
");
  if (p == q)
    printf ("This poem is lame,
It doesn't even rhyme.
");
  else {
    printf("%p is different from %p
", (void*)p, (void*)q);
    printf("%"PRIxPTR" is not the same as %"PRIxPTR"
", pv, qv);
  }
}

这篇关于是否允许编译器回收释放的指针变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆