小工具知识网

当前位置: 首页 > 行业知识 > C++奇迹之旅:C++内存管理的机制(进阶篇)

行业知识

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;}

上一篇:揭秘,黑屎背后的惊人真相!

下一篇:揭秘时时彩计划源码,掌握核心逻辑,轻松赢钱?警惕违法犯罪风险!