笔记_New与Delete_operator new 和 operator delete_内存池

14 篇文章 0 订阅

New与Delete

New不加括号的差别

1>空类的话无区别。
2>有成员变量,带括号的会把一些和成员变量有关的内存清零,并不是整个对象的内存为零
3>当有构造函数的时候,两种写法一致,不会把内存清零了。由构造函数负责了。

class Test3d
{
public:
    Test3d()
    {
        cout << "Init" << endl;
    }
    ~Test3d()
    {
        cout << "Delete" << endl;
    }
};
int main()
{
    Test3d* ptr = new Test3d;
    Test3d* ptr2 = new Test3d;
    delete ptr;
    delete ptr2;
    ptr = nullptr;
    ptr2 = nullptr;
    return 0;
}

New和Delete的运行过程

new


调用了Operate new 
调用了Malloc 分配内存
调用了类的构造函数(如果有的话)


delete


调用了类的析构函数
调用了operate delete
调用了Free释放内存

Delete内存的回收,影响范围很广

class Test3d
{
public:
    void fun()
    {
        char* pp = new char[10];
        memset(pp, 0, 10);
        delete[] pp;
    }
};


回收的字节要超过10个字节,可能会更多
分配的内存也不仅仅是分配10个字节,debug模式下调试信息占有30-60字节,记录分配多少,4个字节等等其他操作

operator new 和 operator delete

//自己实现new和delete
class Test3d
{
public:
    static void* operator new(size_t size);
    static void operator delete(void *phead);
};
void* Test3d::operator new(size_t size)
{
    Test3d* ppoint = (Test3d*)malloc(size);
    return ppoint;
}
void Test3d::operator delete(void* phead)
{
    free(phead);
}

void func()
{
    Test3d* pa = new Test3d();
    delete pa;
}
int main()
{
    func();
    return 0;
}


此处的构造函数和析构函数仍然是编译器帮忙处理
 如果自己不想用自己写的
Test3d* pa = ::new Test3d();
    ::delete pa;

前加双冒号,调用系统的new delete

operator new【】 和 operator delete【】

构造和析构会被调用3次,但是operator new 和delete 仅仅调用一次

class Test3d
{
public:
    static void* operator new[](size_t size);
    static void operator delete[](void *phead);
};
void* Test3d::operator new[](size_t size)
{
    Test3d* ppoint = (Test3d*)malloc(size);
    return ppoint;
}
void Test3d::operator delete[](void* phead)
{
    free(phead);
}

void func()
{
    Test3d* ptr = new Test3d[3];
    delete[] ptr;
}
int main()
{
    func();
    return 0;
}

内存池

作用和原理


作用:减少malloc调用次数,减少内存浪费
原理:先malloc申请一大块内存,分配的时候一点点给,如果不够了,再malloc一大块内存

最简易内存池代码实现

class Test3d
{
public:
    static void* operator new(size_t size);
    static void operator delete(void *phead);
    static int m_iCount;//分配计数统计,new一次统计一次
    static int m_iMallocCount; //分配计数统计,Malloc一次统计一次
private:
    Test3d* next;
    static Test3d* m_FreePos;//内存首地址
    static int m_sTrunkCount;//分配多少倍的内存
};
int Test3d::m_iCount = 0;
int Test3d::m_iMallocCount = 0;
Test3d* Test3d::m_FreePos = nullptr;
int Test3d::m_sTrunkCount = 5;


void* Test3d::operator new(size_t size)
{
    Test3d* tempLink;//需要返回的一个内存块
    if (m_FreePos == nullptr)
    {
        size_t tempSize = m_sTrunkCount * size;
        m_FreePos = reinterpret_cast<Test3d*>(new char[tempSize]);
        tempLink = m_FreePos;
        for (; tempLink!=&m_FreePos[m_sTrunkCount-1]; tempLink++)
        {
            tempLink->next = tempLink + 1;
        }
        tempLink->next = nullptr;
        ++m_iMallocCount;
    }
    ++m_iCount;
    tempLink = m_FreePos;
    m_FreePos = m_FreePos->next;
    return tempLink;
}
void Test3d::operator delete(void* phead)
{
    (static_cast<Test3d*>(phead))->next = nullptr;
    m_FreePos = static_cast<Test3d*>(phead);
}

void func()
{
    clock_t start, end;
    start = clock();
    for (int i = 0;i<500'0000;i++)
    {
        Test3d* ptr = new Test3d();
    }
    end = clock();
    cout << "申请分配内存的次数为:" << Test3d::m_iCount << endl;
    cout << "实际malloc的次数为:" << Test3d::m_iMallocCount << endl;
    cout << "用时为:" << end - start << "毫秒" << endl;
}
int main()
{
    func();
    return 0;
}

注:此版本为最简易版本,可以观察内存池的具体优化时间表现。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值