行业知识
C++奇迹之旅:C++内存管理的机制(进阶篇)
2026-11-04 23:10:43
来源:互联网转载
文章目录
- new和delete操作自定义类型
- operator new与operator delete函数
- operator new与operator delete函数
- new和delete的实现原理
- 内置类型
- 自定义类型
- 定位new表达式(placement-new)
- 总结
new和delete操作自定义类型
我们先看malloc与free,调试可以发现并不会调用析构函数
class A{public:A(int a = 0): _a(a){cout cout A* p1 = (A*)malloc(sizeof(A));free(p1);return 0;}// try to allocate size bytesvoid* p;while ((p = malloc(size)) == 0)if (_callnewh(size) == 0){// report no memory// 如果申请内存失败了,这里会抛出bad_alloc 类型异常static const std::bad_alloc nomem;_RAISE(nomem);}return (p);}_CrtMemBlockHeader* pHead;RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));if (pUserData == NULL)return;_mlock(_HEAP_LOCK); /* block other threads */__TRY/* get a pointer to memory block header */pHead = pHdr(pUserData);/* verify block type */_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead-nBlockUse));_free_dbg(pUserData, pHead-nBlockUse);__FINALLY_munlock(_HEAP_LOCK); /* release other threads */__END_TRY_FINALLYreturn;}// 当b == 0时抛出异常if (b == 0)throw "Division by zero condition!";elsereturn ((double)a / (double)b);}void Func(){int len, time;cin len time;cout try {Func();}catch(const char* errmsg){//当 Division(len, time) 函数抛出这种异常时,异常对象会被赋值给 errmsg 变量。//然后,这个 catch 块会输出 errmsg 的内容,即 "Division by zero condition!"cout //这个 catch 块用于捕获任何其他类型的未知异常。//当 try 块中发生任何其他类型的异常时,这个 catch 块会被执行。//它会输出 "unkown exception"。cout public: // 构造函数 Stack(int initialCapacity = 10) : _a(new int[initialCapacity]) , _top(0) , _capacity(initialCapacity) {} // 析构函数 ~Stack() { delete[] _a; } // 压入元素 void push(int value) { // 如果栈已满,需要扩容 if (_top == _capacity) { resize(2 * _capacity); } // 将元素压入栈顶 _a[_top++] = value; } // 弹出栈顶元素 int pop() { // 如果栈为空,抛出异常 if (_top == 0) { throw runtime_error("Stack is empty"); } // 弹出栈顶元素并返回 return _a[--_top]; } // 判断栈是否为空 bool empty() const { return _top == 0; } // 返回栈中元素的个数 int size() const { return _top; }private: // 扩容函数,分配新的数组空间并移动元素 void resize(int newCapacity) { // 分配新的数组空间 int* newArray = new int[newCapacity]; // 使用 std::move 将原数组中的元素移动到新数组中 move(_a, _a + _top, newArray); // 释放原数组空间 delete[] _a; // 更新数组指针和容量 _a = newArray; _capacity = newCapacity; } // 存储元素的数组指针 int* _a; // 栈顶元素的索引 int _top; // 数组的容量 int _capacity;};int main() { // 创建一个栈 Stack* p3 = new Stack; // 释放栈的内存 delete p3; 压入三个元素 //p3-push(1); //p3-push(2); //p3-push(3); 依次弹出并打印元素 //while (!p3-empty()) //{ // cout public:A(int a = 0): _a(a){cout cout A* p1 = new A;A* p2 = new A[10];delete p1;delete[] p2;return 0;}public:A(int a = 0): _a(a){cout cout // p1现在指向的只不过是与A对象相同大小的一段空间,还不能算是一个对象,因为构造函数没有执行A* p1 = (A*)malloc(sizeof(A));new(p1)A; // 注意:如果A类的构造函数有参数时,此处需要传参p1-~A();free(p1);A* p2 = (A*)operator new(sizeof(A));new(p2)A(10);p2-~A();operator delete(p2);return 0;}