C++ 是不是;printf";阻止数组的释放?

C++ 是不是;printf";阻止数组的释放?,c++,printf,dynamic-memory-allocation,C++,Printf,Dynamic Memory Allocation,当我发现我的输出取决于我是否包含对printf的调用时,我正在为new如何导致内存泄漏以及为什么应该包含相应的delete创建一个示例: #包括 福班{ 公众: 双*阵列; 富(无效){ 数组=新的双精度[16]; 对于(int i=0;i

当我发现我的输出取决于我是否包含对
printf
的调用时,我正在为
new
如何导致内存泄漏以及为什么应该包含相应的
delete
创建一个示例:

#包括
福班{
公众:
双*阵列;
富(无效){
数组=新的双精度[16];
对于(int i=0;i<16;++i)
数组[i]=5+i;
}
~Foo(){
删除[]数组;
}
};
空心钢筋(双**ptr){
福福;
*ptr=f.阵列;
//有关表述:
printf(“ptr=%p\n”,*ptr);
}
int main(int argc,char*argv[]){
double*ptr=NULL;
酒吧和酒店;
printf(“ptr[3]=%4.1f\n”,ptr[3]);
返回0;
}
即,如果我在表达式
printf中离开(“ptr=%p\n”,*ptr),则输出为

ptr=0x7fd7f44058d0

ptr[3]=8.0

但是如果我注释掉这个表达式,那么输出是

ptr[3]=0.0

看来printf是在幕后管理内存

(我知道我无论如何都不应该偷看
ptr[3]
,但我只是好奇为什么会发生这种情况。)

编辑:是的,代码不会很好,即使它没有追求未定义的行为;这里的目标不是解决或预防问题,只是理解为什么会发生。
我想我的问题的答案只是编译器正在做一些有用的事情,而且它会根据
printf
是否存在而得到不同的想法看看你正在创建的对象的生命周期

Foo f;
这存在于Bar()的范围内,但当Bar()退出时,f将被销毁,从而释放您创建的缓冲区

在这一点上,ptr指向某个随机内存位置,该位置可以用于其他任何内容。你再也不能指望它了。你不知道那里会有什么


这是一个彻底的错误。

调用那里的
printf
可能会使编译器重新安排事情,使它们与不调用时不同,并且值可能会在该内存地址中停留一段时间,但您不能(也不应该)指望这一点


正如评论和@Joseph Larson所说,您的构造是一个bug。

未定义的行为是未定义的。也许编译器发现
ptr[3]
从未被合法访问,并优化了一堆代码。由于2000年中期您也不应该使用
new
,您应该使用一个智能指针类来确保指针自动删除。到目前为止,
new
主要(如果不是唯一)是为图书馆作者提供的。自20世纪90年代末以来,这应该是
vector
。No
double**ptr
。可以使用引用代替指针。此代码有几个问题,
new
是最小的问题。此代码很容易导致访问冲突或缓冲区溢出
Foo
类包含指向动态内存的指针,但不符合正确管理该内存的要求。另外,
Bar()
正在输出一个指向已被
Foo
的析构函数释放的内存的悬空指针,因此
main()
中的
printf()
正在从无效内存中读取,因此表现出未定义的行为。在某些情况下,
printf
可以调用
malloc