看我的错误示例代码:
std::vector<CObject*> ObjectSet = std::vector<CObject*>(3000);
CObject* pDataSet = new CObject[3000]();//为了避免产生内存碎片,先分配连续内存
for (unsigned int i=0; i<ObjectSet.size(); ++i)
{
ObjectSet[i] = pDataSet + i;
//ObjectSet[i] = & pDataSet[i]; //作用等同于上一行
}
//释放内存
for (unsigned int i=0; i<ObjectSet.size(); ++i)
{
delete ObjectSet[i];
}
结果运行时出错。在delete第二个Vector中的指针时报错:
然后网上搜集相关知识,总结如下:
对动态内存的分配和释放的机制不理解。这是运行时错误。
上例中,动态内存申请了一份,却释放了3000次!!!!!难怪会报错。。
“CObject* pDataSet = new CObject[3000]();”其本质是:从堆中分配 3000 * sizeof(CObject)大小的内存,并调用3000次CObject的构造函数,初始化分配的动态内存。注意:分配内存时,相关的动态存储管理数据结构(空闲链表或位图)记录了你申请的动态内存的首地址和大小。而且,这片内存在释放的时候只能释放一次! 因为数据结构里就记录了这样一份首地址和大小。释放时,将从首地址开始,连续地在数据结构中指定大小的内存归还给空闲存储区,然后调用析构函数。
delete和delete[]的区别: 如果动态创建一个对象数组,用delete只能对数据的第0个对象元素调用析构函数,其他对象元素不可能调用。而delete[]则对数组中的所有对象元素调用析构函数。如果数组中对象在创建时,其成员也是动态创建的,则用delete必然会内存泄漏。
你的这一句代码delete ObjectSet[i];反复执行,多次释放动态内存,第二次循环时,必然错误。
Tips : 想编程进阶的话,不能只看编程书,操作系统,和数据结构必看。上述就是操作系统中动态存储管理讲解的内容。
内存泄漏:
_CrtDumpMemoryLeaks();//检测内存泄漏
//_CrtSetBreakAlloc(173);//定位内存泄漏