簡體   English   中英

在堆上創建多維數組

[英]Creating multidimensional array on the heap

經過一些實驗,我想出了這四種在堆上創建多維數組的方法(1 和 2 有點相同,除了 1 的結果我想要參考):

#include <memory>
#include <iostream>

template <typename T>
void printArr(T const &arr)
{
    std::cout << typeid(T).name() << "\t";
    for (int x = 0; x < 2; ++x)
        for (int y = 0; y < 2; ++y)
            for (int z = 0; z < 2; ++z)
                std::cout << arr[x][y][z] << " ";
    std::cout << std::endl;
}


int main()
{
    int(&arr)[2][2][2] = reinterpret_cast<int(&)[2][2][2]>(*new int[2][2][2]{ { { 1,2 },{ 3,4 } }, { { 5,6 },{ 7,8 } } });
    printArr(arr);
    delete[] &arr;

    int(*arr2)[2][2] = new int[2][2][2]{ { { 1,2 },{ 3,4 } },{ { 5,6 },{ 7,8 } } };
    printArr(arr2);
    delete[] arr2;

    std::unique_ptr<int[][2][2]> arr3(new int[2][2][2]{ { { 1,2 },{ 3,4 } },{ { 5,6 },{ 7,8 } } });
    printArr(arr3);

    std::unique_ptr<int[][2][2]> arr4 = std::make_unique<int[][2][2]>(2);
    printArr(arr4);

    return 0;
}

在各種在線編譯器上測試了這個沒有問題,所以我想知道它們是否也是有效的方法?

這是演示https://ideone.com/UWXOoW和輸出:

int [2][2][2]   1 2 3 4 5 6 7 8
int (*)[2][2]   1 2 3 4 5 6 7 8
class std::unique_ptr<int [0][2][2],struct std::default_delete<int [0][2][2]> > 1 2 3 4 5 6 7 8
class std::unique_ptr<int [0][2][2],struct std::default_delete<int [0][2][2]> > 0 0 0 0 0 0 0 0

我認為您的第一個示例是未定義的行為,或者至少會在您嘗試通過引用arr實際訪問數組時導致未定義的行為。

new int[2][2][2]創建一個包含兩個int[2][2]的數組。 它返回一個指向該數組第一個元素的指針( [expr.new] §1 )。 但是,指向數組第一個元素的指針和指向數組本身的指針不能相互轉換 我不確定對於哲學問題“取消引用無效指針本身的行為是否已經構成未定義的行為?”是否有明確的答案。 但至少訪問從 reinterpret_cast 獲得的引用肯定會違反嚴格的別名規則 其他三個應該沒問題。

編輯:

由於似乎仍然有些混亂,這里對我的論點進行更詳細的解釋:

new int[2][2][2]

創建兩個陣列int[2][2]和返回一個指向該陣列中,即,指針向第一的第一個元素int[2][2]子對象此陣列,而不是整個陣列對象本身

如果你想從new得到一個int(*)[2][2][2] ,你可以,例如,做

new int[1][2][2][2]

暫無
暫無

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

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