2

目前 Visual C++ 附带运行时,其中malloc()__declspec( restrict ).

MSDN 告诉编译器,这个修饰声明返回的指针malloc()不能被任何其他指针所别名。好的,两个后续调用malloc()确实返回了不同的指针。但是如果我打电话会发生什么

void* memory1 = malloc( 10 );
free( memory1 );
void* memory2 = malloc( 10 );
//here memory1 may be equal to memory2

在这种情况下,两个指针可以指向同一个位置。这与不能被任何其他指针含义所别名有何关联__declspec( restrict )

4

2 回答 2

4

因为一旦你释放(memory1),通过 memory1 指针访问任何东西都是未定义的行为(鼻恶魔等),因此编译器可以优化,假设在 malloc() 调用之后 memory2 没有被任何其他指针别名。

至于为什么这很重要,假设编译器本身没有关于 malloc() 语义的内部信息,即它像对待任何其他函数一样对待它,那么它不能假设返回的指针没有被任何其他指针别名。(__declspec(restrict)或等效地,__attribute__((malloc))在 GCC 中)告诉编译器该指针不被任何其他指针所别名,这允许一些其他情况下不可能的优化。

于 2011-09-23T09:05:46.677 回答
3

该标准对“对象生命周期”有这样的说法(N3290 中的第 3.8 节):

T 类型对象的生命周期在以下情况下结束:
— 如果 T 是具有非平凡析构函数 (12.4) 的类类型,则析构函数调用开始,或者
— 对象占用的存储空间被重用或释放。

在你free'd 指向的块之后memory1,那个对象就死了。它已经不复存在了。取消引用该指针将是未定义的行为。

memory2可以分配相同的内存地址,但它不会“别名”任何东西:那个位置的东西已经过去了。

于 2011-09-23T09:23:05.707 回答