2013-05-10 72 views
2

我很好奇,如果此代码导致内存 泄漏可能是由于我重新指派 指针在第3行,然后在第4行删除它?此代码是否会导致内存泄漏?

谢谢。

1. int y = 12; 
2. int *pt = new int; 
3. pt = &y; 
4. delete pt; 
+0

我认为它崩溃的原因PT没有指向储池内存空间了 – DGomez 2013-05-10 19:36:46

+1

您的代码将更有可能崩溃...... – JosephH 2013-05-10 19:36:50

+0

@DGomez,不必。这是UB。 – chris 2013-05-10 19:37:04

回答

8

它不仅泄露了动态分配的int但也有不确定的行为,因为你不能delete,这不是用new(§5.3.5/ 2)分配一个对象。

delete操作数的值可以是一个空指针值,指针到由先前新表达,或一个指向子对象(1.8)创建了一个非数组对象代表的基这样一个对象的类(第10章)。如果不是,则行为未定义。

因为由y表示的对象不是使用一个新的表达分配,则不能使用delete摧毁它。它的生命周期受其范围支配。

+0

所以我应该小心重新指派指针?我听说在C这是一个问题,虽然没有在C++中体验过。 – user2054339 2013-05-10 19:41:03

+2

@ user2054339你应该小心一般的指针。原始的指针类型对它指向的对象的生命周期几乎没有提及。更喜欢使用更清晰的智能指针。 – 2013-05-10 19:42:02

+0

这是否是一个正确的方法(我知道可能并不优雅,但仍然)删除p1和p2? '\t int * y; \t int * p1 = new int; \t int * p2 = new int; \t y = p1; \t删除y; \t y = p2; \t删除y;' – user2054339 2013-05-10 19:44:38

2

如果它不首先引起崩溃,会导致内存泄漏。

您不应删除具有“自动”存储的对象。

0

是的。

你失去的指针newint的时刻,你泄露

pt = &y; // Here the memory allocated is not reachable now and can not be deleted 

这是UB

delete pt; // pt is pointing to automaticaly allocated memory now. You can't delete that. 
+2

为什么downvote请? – stardust 2013-05-10 19:38:20

+0

可能是因为你没有提到UB方面。如果该程序甚至*存活*删除一个自动对象,那么是的,有*可能*一个泄漏......但第二个'删除'发生,程序跑了轨道。甚至*试图推断超出这一点的行为是毫无意义的。 – cHao 2013-05-10 19:39:34

+0

是啊,真的......我的天赋也被低估了。 – 2013-05-10 19:39:43

0

应该崩溃,因为你assing堆栈ADRESS你的指针,然后删除它。至少它不确定会发生什么。

0

是的,它确实会导致内存泄漏,因为后续分配pt会导致您丢失之前包含内存的分配。如果您在此之前叫过delete pt,那就没问题。

4

每当你不知道的内存泄漏的代码,您可以使用valgrindvalgrind --tool=memcheck来检查他们,但一定要编译代码不使用任何优化,并完全调试模式(例如“G ++ -g”)。

这里是你的程序的输出:

=29667== Memcheck, a memory error detector 
==29667== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. 
==29667== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info 
==29667== Command: ./main 
==29667== 
==29667== Invalid free()/delete/delete[] 
==29667== at 0x4C26DCF: operator delete(void*) (vg_replace_malloc.c:387) 
==29667== by 0x4006AB: main (main.cpp:7) 
==29667== Address 0x7fefffd0c is on thread 1's stack 
==29667== 
==29667== 
==29667== HEAP SUMMARY: 
==29667==  in use at exit: 4 bytes in 1 blocks 
==29667== total heap usage: 1 allocs, 1 frees, 4 bytes allocated 
==29667== 
==29667== LEAK SUMMARY: 
==29667== definitely lost: 4 bytes in 1 blocks 
==29667== indirectly lost: 0 bytes in 0 blocks 
==29667==  possibly lost: 0 bytes in 0 blocks 
==29667== still reachable: 0 bytes in 0 blocks 
==29667==   suppressed: 0 bytes in 0 blocks 
==29667== Rerun with --leak-check=full to see details of leaked memory 
==29667== 
==29667== For counts of detected and suppressed errors, rerun with: -v 
==29667== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4) 

您的代码失去出口处4个字节()。

这里的东西,你可以用做MEMCHECK名单,从工具的website

MEMCHECK是一个内存错误检测。它可以检测到C和C++程序中常见的以下 问题。

  • 访问你不应该的内存,例如溢出和 溢出堆块,溢出堆栈顶部,并在释放后访问内存 。

  • 使用未定义的值,即尚未初始化的值, 或已从其他未定义值派生的值。

  • 堆存储器的不正确的释放,如双释放堆块, 或错配的使用malloc /新的/新的[]对 免费/删除/删除[]

    • 重叠src和在memcpy和相关函数中的dst指针。

    • 内存泄漏。

像这些问题可能很难通过其他手段发现,经常 其余未被发现长时间,然后造成偶尔的, 难以诊断故障。

+0

显示valgrind和用法的荣誉。但是这个实验并没有帮助,因为他的代码还包含未定义的行为(通过在未由'new'分配的东西上调用'delete'),这意味着任何事情都会发生。 – 2013-05-10 19:50:28

+2

@NikBougalis Valgrind检测到无效的'delete':你可以在输出中看到它。如果这没有帮助,我不知道是什么。 – 2013-05-10 19:52:11

+0

我不反对 - 这里有帮助,我应该在我的措辞中更加小心。但我的主要观点是,一旦你遇到未定义的行为*任何事情*,这就是为什么UB **必须明确指出OP。在UB游戏中,valgrind可能已经回到了“没有内存泄漏,你*金*”或者甚至以“嘿性感......”开头的东西,这是*可能* – 2013-05-10 20:00:38

相关问题