std::realloc
來自 cppreference.com
定義於標頭檔案 <cstdlib> |
||
void* realloc( void* ptr, std::size_t new_size ); |
||
重新分配給定的記憶體區域(在目標區域中隱式建立物件)。它必須先前透過 std::malloc、std::calloc 或 std::realloc
分配,並且尚未透過 std::free 釋放,否則結果是未定義的。
重新分配透過以下任一方式完成:
a) 如果可能,擴充套件或收縮 ptr 指向的現有區域。該區域的內容保持不變,直到新舊大小中較小的一個。如果區域被擴充套件,陣列新部分的內容是未定義的。
b) 分配一個大小為 new_size 位元組的新記憶體塊,複製大小等於新舊大小中較小的一個的記憶體區域,並釋放舊塊。
如果記憶體不足,舊記憶體塊不會被釋放,並返回空指標。
如果 ptr 是空指標,則行為與呼叫 std::malloc(new_size) 相同。
如果 new_size 為零,則行為是實現定義的:可能會返回空指標(在這種情況下,舊記憶體塊可能被釋放也可能不被釋放),或者可能會返回某個非空指標,但該指標可能無法用於訪問儲存。 此類用法已棄用(透過 C DR 400)。(C++20 起)
以下函式必須是執行緒安全的
這些函式中分配或解除分配特定儲存單元的呼叫以單一的總順序發生,並且每個這樣的解除分配呼叫先於該順序中的下一個分配(如果有的話)。 |
(C++11 起) |
目錄 |
[編輯] 引數
ptr | - | 指向要重新分配的記憶體區域的指標 |
new_size | - | 陣列的新大小 |
[編輯] 返回值
成功時,返回指向新分配記憶體起始的指標。為避免記憶體洩漏,返回的指標必須透過 std::free 或 std::realloc
釋放。原始指標 ptr 將失效,對其的任何訪問都是未定義行為(即使是原地重新分配)。
失敗時,返回空指標。原始指標 ptr 保持有效,可能需要透過 std::free 釋放。
[編輯] 注意
因為重新分配可能涉及按位元組複製(無論它是擴充套件還是收縮區域),所以這些物件必須是TriviallyCopyable型別是必要的(但不是充分的)。
一些非標準庫定義了一個型別特徵“BitwiseMovable”或“Relocatable”,它描述了一種沒有
- 外部引用(例如,列表或樹的節點,它持有對另一個元素的引用),和
- 內部引用(例如,成員指標,它可能持有另一個成員的地址)的型別。
即使其複製建構函式不是平凡的,此類物件在其儲存重新分配後也可以被訪問。
[編輯] 示例
執行此程式碼
#include <cassert> #include <cstdlib> #include <new> class MallocDynamicBuffer { char* p; public: explicit MallocDynamicBuffer(std::size_t initial = 0) : p(nullptr) { resize(initial); } ~MallocDynamicBuffer() { std::free(p); } void resize(std::size_t newSize) { if (newSize == 0) // this check is not strictly needed, { std::free(p); // but zero-size realloc is deprecated in C p = nullptr; } else { if (void* mem = std::realloc(p, newSize)) p = static_cast<char*>(mem); else throw std::bad_alloc(); } } char& operator[](size_t n) { return p[n]; } char operator[](size_t n) const { return p[n]; } }; int main() { MallocDynamicBuffer buf1(1024); buf1[5] = 'f'; buf1.resize(10); // shrink assert(buf1[5] == 'f'); buf1.resize(1024); // grow assert(buf1[5] == 'f'); }
[編輯] 參閱
C 文件 關於 realloc
|