首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ new 失敗處理:崩潰原理、標準行為與安全用法

     編輯:關於C++

背景

C++ 標準規定 new 失敗拋出 std::bad_alloc。但 Visual C++ 6.0 默認返回 NULL,導致 STL 內部假設失效,引發訪問違規崩潰。

各版本行為差異

版本純 C++ newMFC new
VC6返回 NULL拋 CMemoryException
>=VC7.1拋 std::bad_alloc拋 CMemoryException

VC7.1+ 鏈接順序影響行為:標準庫在前拋異常,CRT 在前返回 NULL。可鏈接 thrownew.obj 強制拋異常。

崩潰案例分析

STL string 擴容時 allocator.allocate 調用 new。若返回 NULL,指針運算 ptr+1 得 0x1,隨後寫入導致 Access Violation。正確流程應捕獲異常重試或傳播。

修正方案:設置 new_handler


#include 
#include 
#pragma init_seg(lib)
namespace {
    int new_handler(size_t) { throw std::bad_alloc(); return 0; }
    struct NewHandler {
        NewHandler() { _set_new_handler(new_handler); }
        ~NewHandler() { _set_new_handler(nullptr); }
    } g_NewHandler;
}

包含此代碼後,new 失敗將拋出 std::bad_alloc,STL 行為恢復正常。

nothrow new 注意

new (std::nothrow) 在 VC6 優化下可能導致異常終止,需關閉優化或自行實現。

最佳實踐

  1. 現代編譯器 (VS2005+) 默認標準行為,無需特殊處理。
  2. 舊代碼遷移時,務必添加 new_handler 確保拋異常。
  3. 捕獲內存耗盡:catch (const std::bad_alloc&) 或 catch (...) (MFC/STL 混用時)。
  4. 嚴禁不檢查指針直接使用(雖標準保證拋異常,但 nothrow 版需檢查)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved