C++对象对new,delete拦截实现内存监视

object_memory_monitoring - 源码文件 - 点击下载

C或C语言和其他语言不同,需要自己管理内存,对不需要的内存要及时释放,否则就会导致内存泄露,导致内存不足让程序崩溃。
在C程序员中,很容易导致内存忘记释放,特别是在程序出现异常的情况下。
在对象中我们可以对new,delete进行重写,实现内存监视

#include <iostream>
#include <stdlib.h>

using namespace std;

class man
{
public:
    //计数器
    static int jishuqi;
    //用于指向头结点
    static man * head;
    //用于指向当前节点
    static man * local;
    man * next;
    man()
    {
        //cout << "man preject init!" << endl;
    }
    ~man()
    {
        //cout << "man preject end!" << endl;
    }
    static void * operator new(size_t size)
    {
        man *ptemp = ::new man;
        ptemp->next = NULL;
        if(head == NULL){
            head = ptemp;
        }
        if(local == NULL){
            local = ptemp;
        }
        else{
            local->next = ptemp;
            local = ptemp;
        }
        jishuqi += 1;
        cout << "man preject building! jishuqi = " << jishuqi << " address = " << ptemp << endl;
        return ptemp;
    }
    static void operator delete(void *p)
    {
        //用于指向当前节点
        man * a = head;
        //用于指向当前节点的上一个节点
        man * b = head;
        //在内存链表中查找将要删除的地址
        while(a != NULL){
            cout << "a = " << a << endl;
            cout << "b = " << b << endl;
            //查找到地址
            if( a == p ){
                //如果将要删除的地址在内存链表中是头结点
                if(a == head ){
                    //如果链表中只有一个结点,即头结点,就重新初始化链表
                    if( a->next == NULL ){
                        head = NULL;
                        local = NULL;
                    }
                    //如果链表有多个个结点,将头结点的next指向第二个结点
                    else{
                        head = a->next;
                    }
                }
                //如果将要删除的地址在内存链表中是尾结点,就将尾结点的上一个节点指向NULL,将local指针指向尾结点的上一个节点
                else if( a->next == NULL){
                    b->next = NULL;
                    local = b;
                }
                //如果将要删除的地址在内存链表中是中间节点,就被删除节点的next指针 赋值给 将被删除节点的上一个节点的next指针
                else{
                    b->next = a->next;
                }
                break;
            }
            b = a;
            //指针后移
            a = a->next;
        }
        jishuqi -= 1;
        cout << "man preject delete! jishuqi = " << jishuqi << " address = " << p << endl;
        ::delete p;
    }
    //清除所有类
    static void clean()
    {
        man * a = head;
        man * b = NULL;
        while(a != NULL){
            cout << "a = " << a << endl;
             b = a->next;
             delete a;
             a = b;
        }
    }
};

int man::jishuqi = 0;
man * man::head = NULL;
man * man::local = NULL;


void test(){
    man * wnh1 = new man;
    man * wnh2 = new man;
    man * wnh3 = new man;
    man * wnh5 = new man;
    man * wnh6 = new man;
    man * wnh7 = new man;
    man * wnh8 = new man;
    system("pause");
    cout << "测试删除头指针指向的对象 " << endl;
    delete wnh1;
    system("pause");
    man * a = wnh2->head;
    while(a != NULL){
        cout << "a = " << a << endl;
        a = a->next;
    }
    system("pause");

    cout << "测试删除中间指针指向的对象 " << endl;
    delete wnh5;
    system("pause");
    a = wnh2->head;
    while(a != NULL){
        cout << "a = " << a << endl;
        a = a->next;
    }
    system("pause");

    cout << "测试删除最后指针指向的对象 " << endl;
    delete wnh8;
    system("pause");
    a = wnh2->head;
    while(a != NULL){
        cout << "a = " << a << endl;
        a = a->next;
    }
    system("pause");

    cout << "测试删除最后指针指向的对象重新创建对象时,local指针指向是否正常 " << endl;
    man * wnh9 = new man;
    system("pause");
    a = wnh2->head;
    while(a != NULL){
        cout << "a = " << a << endl;
        a = a->next;
    }
    system("pause");

    cout << "测试删除全部对象后,head和local指针指向是否正常 " << endl;

    man::clean();
    //delete wnh2;
    //delete wnh3;
    //delete wnh6;
    //delete wnh7;
    //delete wnh9;
    system("pause");
    man * wnh10 = new man;
    system("pause");
    a = wnh2->head;
    while(a != NULL){
        cout << "a = " << a << endl;
        a = a->next;
    }
    system("pause");
}

int main()
{
    test();
    system("pause");
    return 0;
}

结果

man preject building! jishuqi = 1 address = 001978D0
man preject building! jishuqi = 2 address = 00197900
man preject building! jishuqi = 3 address = 00197930
man preject building! jishuqi = 4 address = 00197990
man preject building! jishuqi = 5 address = 001979C0
man preject building! jishuqi = 6 address = 001979F0
man preject building! jishuqi = 7 address = 00197A20
请按任意键继续. . .
测试删除头指针指向的对象
a = 001978D0
b = 001978D0
man preject delete! jishuqi = 6 address = 001978D0
请按任意键继续. . .
a = 00197900
a = 00197930
a = 00197990
a = 001979C0
a = 001979F0
a = 00197A20
请按任意键继续. . .
测试删除中间指针指向的对象
a = 00197900
b = 00197900
a = 00197930
b = 00197900
a = 00197990
b = 00197930
man preject delete! jishuqi = 5 address = 00197990
请按任意键继续. . .
a = 00197900
a = 00197930
a = 001979C0
a = 001979F0
a = 00197A20
请按任意键继续. . .
测试删除最后指针指向的对象
a = 00197900
b = 00197900
a = 00197930
b = 00197900
a = 001979C0
b = 00197930
a = 001979F0
b = 001979C0
a = 00197A20
b = 001979F0
man preject delete! jishuqi = 4 address = 00197A20
请按任意键继续. . .
a = 00197900
a = 00197930
a = 001979C0
a = 001979F0
请按任意键继续. . .
测试删除最后指针指向的对象重新创建对象时,local指针指向是否正常
man preject building! jishuqi = 5 address = 00197A20
请按任意键继续. . .
a = 00197900
a = 00197930
a = 001979C0
a = 001979F0
a = 00197A20
请按任意键继续. . .
测试删除全部对象后,head和local指针指向是否正常
a = 00197900
a = 00197900
b = 00197900
man preject delete! jishuqi = 4 address = 00197900
a = 00197930
a = 00197930
b = 00197930
man preject delete! jishuqi = 3 address = 00197930
a = 001979C0
a = 001979C0
b = 001979C0
man preject delete! jishuqi = 2 address = 001979C0
a = 001979F0
a = 001979F0
b = 001979F0
man preject delete! jishuqi = 1 address = 001979F0
a = 00197A20
a = 00197A20
b = 00197A20
man preject delete! jishuqi = 0 address = 00197A20
请按任意键继续. . .
man preject building! jishuqi = 1 address = 00197A20
请按任意键继续. . .
a = 00197A20

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章