14. 对象池newnew[ ]deletedelete[ ]混用
Posted 为了财务自由!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了14. 对象池newnew[ ]deletedelete[ ]混用相关的知识,希望对你有一定的参考价值。
new和delete
malloc和new区别
- malloc按字节开辟内存;new开辟内存时需要指定类型new int[10]
所以malloc开辟内存返回的都是void* ,上面的operator new返回的是int*- malloc只负责开辟空间,new不仅仅有malloc的功能,可以进行数据的初始化new int(20);new int20;(20个元素初始化为0)
- malloc开辟内存失败返回nullptr指针;new抛出来的是bad_alloc类型的异常
free和delete区别?
- delete:调用析构函数;再free。
void* operator new(size_t size)
void* p = malloc(size);
if(p==nullptr)
throw bad_alloc();
return p;
void operator delete(void* ptr)
free(ptr);
void* operator new[](size_t size)
void *p = malloc(size);
if (p == nullptr)
throw bad_alloc();
return p;
void operator delete(void* ptr)
free(ptr);
int main()
try
int* p = new int;
delete p;
catch(const bad_alloc& err)
cerr << err.what() << endl;
return 0;
new和delete能混用嘛?为什么要区分单个元素和数组的申请和释放?
对于普通的编译器内置类型 new/delete[] new[]/delete 可以混合使用
自定义的类类型,有析构函数,为了调用正确的析构函数,那么开辟对象数组的时候,
会多开辟4个字节,记录对象的个数,不能混合使用!
new T[size]如果用delete,那么就相当于从0x104开始释放,很明显必须从0x100开始释放才是合法的,所有T是自定义类类型的话,直接报错!delete认为只有一个对象,把T[0]析构,然后free,底层内存其实是从0x100开始的!
对象池!
template<typename T>
class Queue
public:
Queue()
//指向头节点!
_front = _rear = new QueueItem();
~Queue()
QueueItem* cur = _front;
while(cur != nullptr)
_front = _front->_next;
delete cur;
cur = _front;
void push(const T& val)
QueueItem* item = new QueueItem(val);
_rear->_next = item;
_rear = item;
void pop()
if(empty())
return ;
QueueItm* first = _front->_next;
_front->_next = first->_next;
if(_front->_next == nullptr)
_rear = _front;
delete first;
T front() const
return _front->_next->_data;
private:
struct QueueItem
//对象池(10000个QueueItem结点!)
QueueItem(T data=T())
:_data(data),_next(nullptr)
void* operator new(size_t size)
if(_itemPool == nullptr)
_itemPool = (QueueItem*)new char[POOL_ITEM_SIZE * sizeof(QueueItem)];
QueueItem* p = _itemPool;
for(;p<_itemPool+POOL_ITEM_SIZE-1;++p)
p->_next = p+1;
p->_next = nullptr;//最后一个地址域为nullptr
QueueItem* p = _itemPool;
_itemPool = _itemPool->_next;
return p;
void operator delete(void* ptr)
QueueItem* p = (QueueItem*)ptr;
p->_next = _itemPool;
_itemPool = p;
T _data;
QueueItem* _next;
//新特性里面static可以在类内初始化!
static const int POOL_ITEM_SIZE=100000;
static QueueItem* _itemPool;
;
QueueItem* _front;//指向头节点
QueueItem* _rear;//指向队尾
:
//类外初始化!
template<typename T>
typename Queue<T>::QueueItem* Queue<T>::QueueItem::itemPool = nullptr;
那么对象池用完了,咋办?
不影响,到池子最后一个对象时,_next域为空,new的时候判断到为空,那么继续申请池子!
以上是关于14. 对象池newnew[ ]deletedelete[ ]混用的主要内容,如果未能解决你的问题,请参考以下文章
如何在计时器上更改python customedraw文本?怎么样?