重载new与delete

  • new和delete的机制

new分3步,首先new表达式用一个名为operarot new或者operator new[]的标准库函数来分配一块足够大的原始内存;然后编译器运行相应的构造函数来构造;最后构造完成之后返回一个指向该对象的指针。delete分2步,首先对指针指向的内存执行析构操作,然后调用operator delete或者operator delete[]释放相应空间。

  • 默认的new,new[],delete,delete[]
    void* operator new(size_t)
    void* operator new[](size_t)
    void operator delete(void*)
    void operator delete[](void*)
    注意对于重载new与new[],必须返回void,并且第一个参数必须是size_t,且不能有默认实参,`void operator new(size_t, void*)` 这种形式不能重载,只能供标准库使用。

  • 运用重载new与delete来检测内存泄露
    内存泄漏就是new出来的内存没有通过delete合理的释放掉。new和delete这两个函数就是关键点。可以重载new和delete,每次new中开辟一块内存就用链表把这个内存的信息保存下来,每次用delete删除一块内存就从链表中删除这块内存的记录。代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    #include <iostream>
    using namespace std;



    struct node
    {
    unsigned int line;
    void* ptr;
    node* next;
    };

    class mem_list
    {
    public:
    void insert(unsigned int line, void* ptr)
    {

    node* p_node = (node*) malloc(sizeof(node));
    p_node->line = line;
    p_node->ptr = ptr;
    p_node->next = nullptr;

    if(head == nullptr)
    {
    head = p_node;
    }
    else
    {
    p_node->next = head;
    head = p_node;
    }
    }

    void remove(void* ptr)
    {

    node* p_cur = head;
    node* p_pre = nullptr;
    while(p_cur != nullptr)
    {
    if(p_cur->ptr == ptr)
    {
    break;
    }
    else
    {
    p_pre = p_cur;
    p_cur = p_cur->next;
    }
    }

    if(p_cur == nullptr)
    {
    cout << "delete an unknown memory!" << endl;
    }
    else
    {
    p_pre->next = p_cur->next;
    free(p_cur);
    p_cur = nullptr;
    }
    }

    void print()
    {

    if(head == nullptr)
    {
    cout << "no memory leak!" << endl;
    }
    else
    {
    node* p_cur = head;
    while(p_cur != nullptr)
    {
    cout << "a memory leak in line: " << p_cur->line << endl;
    p_cur = p_cur->next;
    }
    }
    }

    private:
    node* head;
    };

    mem_list li; //全局的链表


    void* operator new(size_t size, unsigned int line)
    {

    void* ptr = malloc(size);
    li.insert(line, ptr);
    return ptr;
    }

    void operator delete(void* ptr)
    {

    free(ptr);
    li.remove(ptr);
    }

    #define new new(__LINE__) //关键的一步



    int main()
    {

    unsigned int l = 111;
    int* p = new int;
    li.print();
    return 0;
    }