首頁 > 後端開發 > C++ > 在 C 數組上使用佈局是可移植的新功能嗎?

在 C 數組上使用佈局是可移植的新功能嗎?

DDD
發布: 2024-11-18 05:38:02
原創
709 人瀏覽過

Is Using Placement New on C   Arrays Portable?

陣列的可移植放置新功能

標準庫的放置新運算子允許在指定位址分配記憶體。然而,由於傳回的指標和傳入的位址之間可能存在差異,它與陣列一起使用會引起對可移植性的擔憂。

理解問題

使用placement new時數組,傳回的指標可能與提供的位址不一致。 C 標準 5.3.4 的註 12 對此進行了解釋。因此,專門為數組分配緩衝區會出現問題。

請考慮以下範例:

#include <iostream>
#include <new>

class A {
public:
    A() : data(0) {}
    ~A() {}
    int data;
};

int main() {
    const int NUMELEMENTS = 20;

    char *pBuffer = new char[NUMELEMENTS * sizeof(A)];
    A *pA = new(pBuffer) A[NUMELEMENTS];

    // Output may show pA as four bytes higher than pBuffer
    std::cout << "Buffer address: " << pBuffer << ", Array address: " << pA << std::endl;

    delete[] pBuffer;

    return 0;
}
登入後複製

此範例通常會導致 Microsoft Visual Studio 下的記憶體損壞。對記憶體的檢查表明,編譯器在數組分配前添加了四個字節,可能存儲數組元素的計數。此行為因所使用的編譯器和類別而異。

可移植解決方案

要解決此可移植性問題,請避免直接在陣列上使用放置 new。相反,請考慮使用放置 new 單獨分配數組的每個元素:

#include <iostream>
#include <new>

class A {
public:
    A() : data(0) {}
    ~A() {}
    int data;
};

int main() {
    const int NUMELEMENTS = 20;

    char *pBuffer = new char[NUMELEMENTS * sizeof(A)];
    A *pA = (A*)pBuffer;

    for (int i = 0; i < NUMELEMENTS; ++i) {
        pA[i] = new (pA + i) A();
    }

    std::cout << "Buffer address: " << pBuffer << ", Array address: " << pA << std::endl;

    // Remember to manually destroy each element
    for (int i = 0; i < NUMELEMENTS; ++i) {
        pA[i].~A();
    }

    delete[] pBuffer;

    return 0;
}
登入後複製

無論採用哪種方法,在刪除緩衝區之前手動銷毀每個數組元素對於防止記憶體洩漏至關重要。

以上是在 C 數組上使用佈局是可移植的新功能嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板