簡體   English   中英

如何使用 new 運算符檢查內存分配失敗?

[英]How to check memory allocation failures with new operator?

就在最近,我將項目的語言從 C 切換為使用 C++。對於 C,我使用了 malloc,然后我檢查 malloc 是否成功,但是對於 C++,我使用“new”來分配內存,我想知道你如何通常會檢查內存分配失敗。

從我的谷歌搜索中,我看到了如下所示的 nothrow。

char *buf = new (nothrow)char[10];

我還看到了以下內容。

try{} catch(bad_alloc&) {}

但是下面的呢? 我正在使用一些 chrome 庫例程來使用智能指針。

例如,我的代碼如下。

scoped_array<char> buf(new char[MAX_BUF]);

使用智能指針很棒,但我不確定應該如何檢查內存分配是否成功。 我需要用 nothrow 或 try/catch 分成兩個單獨的語句嗎? 你通常如何在 C++ 中進行這些檢查?

任何建議將被認真考慮。

好吧,你調用 new 拋出bad_alloc ,所以你必須抓住它:

try
{
    scoped_array<char> buf(new char[MAX_BUF]);
    ...
}
catch(std::bad_alloc&) 
{
    ...
}

或者

scoped_array<char> buf(new(nothrow) char[MAX_BUF]);
if(!buf)
{
   //allocation failed
}

我的回答的意思是智能指針傳播異常。 因此,如果您使用普通的 throw new 分配內存,則必須捕獲異常。 如果您使用 nothrow new 進行分配,則必須檢查nullptr 在任何情況下,智能指針都不會向此邏輯添加任何內容

我不想這么說,但是 IMO,你走錯了方向(不幸的是,你得到的其他答案也沒有真正為你指明正確的方向)。

與其在不同種類的智能指針和/或new普通變體和 nothrow 變體之間進行選擇,您可能應該從您正在做的事情中至少再退兩步,並用集合替換手動管理的動態數據結構。 這可能並不總是正確的選擇,但至少在我的經驗,這是更往往不是走了很多正確的方式。 標准庫有多種可能性(向量、雙端隊列、列表、集合等),而且很有可能您可以使用其中之一,而不是直接與new和 company 打交道。

默認情況下,那些將使用最終使用new的正常(拋出)變體的分配器。 因此,您通常希望將大部分代碼放在一個相當高級別的try塊中,並有一個catch子句來處理那里的內存不足。

當/如果您確實需要直接處理分配內存的問題,很有可能您仍然希望提供一個類似於庫中標准容器的接口,以便它可以與普通算法和迭代器一起使用。 當您到達這一點時,您使用現有容器的初步經驗將得到很好的回報,即使它可能還有很長的路要走。

在 C++ 中, new有兩種主要的內存分配方式,每種方式都需要不同的錯誤檢查。

標准new運算符將在失敗時拋出std::bad_alloc異常,這可以像普通異常一樣處理

try {
  char* c = new char[100];
} catch (std::bad_alloc&) {
  // Handle error
}

或者替代的nothrow版本的new將在失敗時簡單地返回NULL

char* c = new (std::nothrow) char[100];
if (!c) {
  // Handle error
}

我很好奇當分配失敗時你期望做什么? 如果沒有可用於分配對象的內存,則在此過程中通常可以完成的工作很少。

您仍然需要檢查內存分配失敗。

任何一個

scoped_array<char> buf;

try {
  buf.reset( new char[MAX_BUF] );
} catch( std::bad_alloc& ) {
  // Handle the failure
}

或者

scoped_array<char> buf( new(std::nothrow)char[MAX_BUF] );

if( buf.get() == NULL ) {
   // Handle the failure
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM