首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ new 超大陣列不報錯?整數溢位導致分配 0 位元組

     編輯:程式設計綜合問答

現象

char* p = new char[1024*1024*1024*1024*1024]; // 1 PB
// 不拋 bad_alloc,p 非 null

根本原因

  1. 1024*1024*1024*1024*1024 為 int 字面常數運算,32 位元有號整數溢位,結果為 0。
  2. new char[0] 依 C++ 標準允許,回傳非 null 唯一指標(不分配儲存空間)。
  3. 若寫入 p[0] 即屬未定義行為 (UB)。

驗證程式碼

#include <iostream>
#include <cstddef>
int main() {
    size_t sz = 1024*1024*1024*1024*1024; // 依然溢位,需加 ULL
    std::cout << "sz = " << sz << '\n';   // 輸出 0

    size_t sz2 = 1024ULL*1024*1024*1024*1024; // 正確 1 PB
    std::cout << "sz2 = " << sz2 << '\n';     // 1125899906842624

    // 實際分配 1 PB 會拋 std::bad_alloc (記憶體不足)
    try {
        char* p = new char[sz2];
        std::cout << "allocated (unexpected)\n";
        delete[] p;
    } catch (std::bad_alloc&) {
        std::cout << "bad_alloc as expected\n";
    }
}

正確寫法

  • 使用 size_t 或 uint64_t 字面常數:1024ULL * 1024 * 1024 * 1024 * 1024。
  • 檢查回傳指標(雖然 new 失敗會拋異常,nothrow 版本才回傳 null)。
  • 大量記憶體分配前評估系統可用記憶體,考慮記憶體對映檔案或分塊處理。

延伸知識

32 位元程式最大位址空間 4 GB,64 位元理論 16 EB,受限於實體 RAM + 頁面檔。單次 new 申請超大塊易失敗,建議使用 std::vector 配合 reserve 或分批分配。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved