从两个内存泄漏的例子说起

例一

//Ver 1
#include <iostream>
#include <Windows.h>

using namespace std;

struct st
{
    int  a;
    ~st()
    {
        cout << "the destructor is called" << endl;
    };
};

st* test()
{
    st mystru;
    mystru.a = 10;
    return &mystru;
}

int main()
{
    st* p = test();
    //此时的 p 应该已经算野指针了
    cout << p->a << endl;          //10
    //重新 new 一个 st,对其 a 赋值
    st* pp = new st;
    pp->a = 11;
    //再输出 p 指向内存处的 a
    cout << p->a << endl;          //4
    system("pause");
    return 0;
}

在第一个例子中,从 结构体的析构函数的执行情况可以看出,mystur 确实被析构了,此时 p 是野指针,但释放并不彻底,程序只是不再拥有对那块内存的所有权,但内存上的内容却没有清空,就导致在 main 中依然可以 通过 p 访问那里的 int a 的数值,然而如果下面通过 new 在堆区创建一个 新的 st 实例,再次输出 p 处的 int a 数值就改变了,这证明了 p 是野指针。

也可以不在堆上新建变量,而在栈上。总之让内存发生改变即可

//Ver 2
#include <iostream>
#include <Windows.h>

using namespace std;

struct st
{
    int  a;
    ~st()
    {
        cout << "the destructor is called" << endl;
    };
};

st* test()
{
    st mystru;
    mystru.a = 10;
    return &mystru;
}

int main()
{
    st* p = test();
    //此时的 p 应该已经算野指针了
    cout << p->a << endl;          //10
    st pp;
    pp.a = 11;
    //再输出 p 指向内存处的 a
    cout << p->a << endl;          //4
    system("pause");
    return 0;
}

例二

#include <cstdio>
#include <Windows.h>

void test()
{
    char c[] = "ChenHuiHui";
}

int main()
{
    printf("" - 13);//这个数字可能和平台有关
    system("pause");
    return 0;
}

这个例子,展示了 静态常量区的内存泄漏 如果使用 iostream 头文件,此问题不存在