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
。Nodouble**ptr
。可以使用引用代替指针。此代码有几个问题,new
是最小的问题。此代码很容易导致访问冲突或缓冲区溢出Foo
类包含指向动态内存的指针,但不符合正确管理该内存的要求。另外,Bar()
正在输出一个指向已被Foo
的析构函数释放的内存的悬空指针,因此main()
中的printf()
正在从无效内存中读取,因此表现出未定义的行为。在某些情况下,printf
可以调用malloc