我在C ++中有以下结构(不要问我为什么不使用std::vector
而不是C数组,这不是问题。)
struct Pizza {
int w;
int h;
char** pizza;
Pizza(int width, int height) {
w = width;
h = height;
pizza = new char*[w];
for (int x = 0; x < w; x++) {
pizza[x] = new char[h];
for (int y = 0; y < h; y++) {
pizza[x][y] = '\0';
}
}
}
~Pizza() {
for (int x = 0; x < w; x++) {
delete[] pizza[x];
}
delete[] pizza;
}
};
我正在使用VS2015并且正在使用:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
与
_CrtDumpMemoryLeaks();
检测内存泄漏,并惊讶地发现我的内存泄漏时出现以下代码:
int main() {
Pizza p(10,10);
_CrtDumpMemoryLeaks();
}
因为我的印象是_CrtDumpMemoryLeaks()
只会在执行后检测并显示内存泄漏(因此会调用Pizza析构函数)。事实证明以下代码
int main() {
Pizza *p = new Pizza(10,10);
delete p;
_CrtDumpMemoryLeaks();
}
不会产生内存泄漏。我只是误解了MSDN中的这句话:
您可以在应用程序退出之前调用_CrtDumpMemoryLeaks 指向应用程序退出时显示内存泄漏报告
或者还有其他事情发生在这里?
我在期待:
int main() {
Pizza p(10,10);
// Imaginary p.~Pizza();
_CrtDumpMemoryLeaks();
}
发生,即首先调用析构函数,而不是:
int main() {
Pizza p(10,10);
_CrtDumpMemoryLeaks();
// Imaginary p.~Pizza();
}
将在之后调用析构函数。
修改: 泄漏报告:
Detected memory leaks!
Dumping objects ->
{170} normal block at 0x01364070, 10 bytes long.
Data: < (2<FPZd> 0A 14 1E 28 32 3C 46 50 5A 64
{169} normal block at 0x013642D8, 10 bytes long.
Data: < $-6?HQZ> 09 12 1B 24 2D 36 3F 48 51 5A
{168} normal block at 0x01364380, 10 bytes long.
Data: < (08@HP> 08 10 18 20 28 30 38 40 48 50
{167} normal block at 0x013640E0, 10 bytes long.
Data: < #*18?F> 07 0E 15 1C 23 2A 31 38 3F 46
{166} normal block at 0x01364658, 10 bytes long.
Data: < $*06<> 06 0C 12 18 1E 24 2A 30 36 3C
{165} normal block at 0x013644D0, 10 bytes long.
Data: < #(-2> 05 0A 0F 14 19 1E 23 28 2D 32
{164} normal block at 0x01364348, 10 bytes long.
Data: < $(> 04 08 0C 10 14 18 1C 20 24 28
{163} normal block at 0x013645E8, 10 bytes long.
Data: < > 03 06 09 0C 0F 12 15 18 1B 1E
{162} normal block at 0x013643B8, 10 bytes long.
Data: < > 02 04 06 08 0A 0C 0E 10 12 14
{161} normal block at 0x01364700, 10 bytes long.
Data: < > 01 02 03 04 05 06 07 08 09 0A
{160} normal block at 0x0135DCA8, 40 bytes long.
Data: < G6 C6 E6 HC6 > 00 47 36 01 B8 43 36 01 E8 45 36 01 48 43 36 01
Object dump complete.
在这里,我使用(x+1)*(y+1)
来填充值。
答案 0 :(得分:3)
如果程序退出,你显然没有任何内存泄漏,因为所有内存都被传回操作系统。获取析构函数的最简单方法是添加另一个范围:
int main() {
{
Pizza p(10,10);
}
_CrtDumpMemoryLeaks();
}
答案 1 :(得分:3)
如文章中所述,您linked in the question:
如果您的应用程序有多个退出,则无需在每个出口点手动调用_CrtDumpMemoryLeaks。在应用程序开头调用
_CrtSetDbgFlag
将导致在每个出口点自动调用_CrtDumpMemoryLeaks
。您必须设置此处显示的两个位字段:_CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
。
所以,您可以调用它,如下所示:
int main ()
{
_CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
// Your actual code
}