再回顾一下new和malloc的区别
(重点!!!面试必问)new和malloc 的区别
1、malloc的返回值不安全需要进行类型转换,而new不需要。
2、new是一个关键字、malloc是一个函数
3、malloc需要用户输入开辟内存的字节大小,呢问,不需要计算开辟内存的大小。
4、new开辟内存失败抛出bad_alloc异常,malloc开辟内存失败返回空指针
5、malloc在堆上开辟内存,new开辟的空间叫做自由存储区。
6、malloc只能开辟空间不负责初始化,new不仅可以开辟空间还可以初始化
7、开辟动态数组的时候new [i] 而malloc(总字节数)
new
1、开辟内存
operator new系统
2、调用构造函数
delete
1、调用析构函数
2、释放对象的内存
new和delete混用:在没有进行初始化的时候数组和单个元素之间的new和delete可以混合使用
new Test[5]实际上开辟的字节还要加4个字节,用来存储对对象个数
自定义的类类型,有析构函数,为了调用正确的析构函数,那么开辟对象数组的时候,会多开辟四个字节,记录对象个数
内存池
**/*
静态链表要用指针而不用游标是因为游标可能无法唯一标识内存单元
*/
const int MEM_SIZE = 3;
template<typename T>
class MEM_POOL
{
public:
static MEM_POOL<T>* getInstance()
{
if (ppm == NULL)
{
ppm = new MEM_POOL<T>();
}
return ppm;
}
void* alloc(size_t size)
{
if (pool == NULL)// 扩容
{
pool = (Node*)new char[(size + 4) * MEM_SIZE]();
Node* pCur = pool;
for (pCur; pCur < pool + MEM_SIZE - 1; pCur = pCur + 1)
{
pCur->pnext = pCur + 1;
}
pCur->pnext = NULL;
}
void* rt = pool;
pool = pool->pnext;
return rt;
}
void dealloc(void* ptr)
{
Node* nptr = (Node*)ptr;
if (nptr == NULL)
{
return;
}
nptr->pnext = pool;
pool = nptr;
}
private:
MEM_POOL()
{
pool = NULL;
}
MEM_POOL(const MEM_POOL<T>&);
struct Node//
{
public:
Node(T value = T())
:val(value), pnext(NULL)
{}
public:
T val;
Node* pnext;
};
Node* pool;
static MEM_POOL<T>* ppm;
};
template<typename T>
MEM_POOL<T>* MEM_POOL<T>::ppm = NULL;
#include<string>
class Student
{
public:
Student(std::string name, std::string id, int age)
:mname(name), mid(id), mage(age)
{}
void* operator new(size_t size)
{
return pmm->alloc(size);
}
void operator delete(void* ptr)
{
pmm->dealloc(ptr);
}
private:
std::string mname;
std::string mid;
int mage;
static MEM_POOL<Student>* pmm;
};
MEM_POOL<Student>* Student::pmm = MEM_POOL<Student>::getInstance();
int main()
{
Student* pstu1 = new Student("zhangsan", "001", 20);
Student* pstu2 = new Student("lisi", "002", 19);
Student* pstu3 = new Student("zhangsan", "001", 20);
Student* pstu4 = new Student("lisi", "002", 19);
delete pstu1;
delete pstu2;
delete pstu3;
delete pstu4;
return 0;
}**
用内存池实现一个队列:
template<typename T>
class Queue
{
public:
Queue()
{
pfront = ptail = new QueueItem();
}
~Queue()
{
QueueItem* pCur = pfront;
QueueItem* pNext;
while (pCur != NULL)
{
pNext = pCur->pnext;
delete pCur;
pCur = pNext;
}
pfront = ptail = NULL;
}
void push(T val)
{
QueueItem* pnewitem = new QueueItem(val);
ptail->pnext = pnewitem;
ptail = ptail->pnext;
}
bool empty()
{
return (pfront == ptail) && (pfront != NULL);
}
void pop()
{
if (empty())
{
throw std::exception("queue is empty!");
}
QueueItem* pdelete = pfront->pnext;
pfront->pnext = pdelete->pnext;
delete pdelete;
}
T front()
{
if (empty())
{
throw std::exception("queue is empty!");
}
return pfront->pnext->mdata;
}
T back()
{
if (empty())
{
throw std::exception("queue is empty!");
}
return ptail->mdata;
}
private:
class QueueItem
{
public:
QueueItem(T val = T())
:mdata(val), pnext(NULL)
{}
void* operator new(size_t size)
{
if (pool == NULL)
{
pool = (QueueItem*)new char[size * 10]();
QueueItem* pCur = pool;
for (pCur; pCur < pool + 10 - 1; pCur = pCur + 1)
{
pCur->pnext = pCur + 1;
}
pCur->pnext = NULL;
}
void* rt = pool;
pool = pool->pnext;
return rt;
}
void operator delete(void* ptr)
{
if (ptr == NULL)
{
return;
}
QueueItem* pptr = (QueueItem*)ptr;
pptr->pnext = pool;
pool = pptr;
}
public:
T mdata;
QueueItem* pnext;
};
QueueItem* pfront;
QueueItem* ptail;
static QueueItem* pool;
};
template<typename T>
typename Queue<T>::QueueItem* Queue<T>::pool = NULL;
int main()
{
Queue<int> que;
for (int i = 0; i < 3; i++)
{
que.push(i + 1);
}
int rt = que.front();
que.pop();
std::cout << "rt:" << rt << std::endl;
return 0;
}