2D动态阵列逻辑

时间:2018-08-13 16:45:29

标签: c++ pointers

我正在学习c ++指针。我写了一些代码看我是否理解正确。

看起来可能有点怪异。我的目的有点复杂。你能告诉我我是否理解正确?还是有我不明白的问题?

#include <iostream>

using namespace std;

int main()
{
    int **x = new int*[20];
    *x      = new int [5]; //x[0] ==>[0,0,0,0,0]
    *(x+1)  = new int [3]; //x[1] ==>[0,0,0] 

    *x[0]     = 10; //x[0][0] = 10
    *(x+1)[0] = 20; //x[1][0] = 20

    cout << x[0][0] << endl;
    cout << x[1][0] << endl;

    delete [] *x;
    delete [] *(x+1);
    delete [] x;

    return 0;
}

3 个答案:

答案 0 :(得分:4)

由于operator precedence,第

*x[0]     = 10;
*(x+1)[0] = 20;

等同于

*(x[0])     = 10;
*((x+1)[0]) = 20;

我不确定你是否是那样的。 IMO,最好使用:

(*x)[0]     = 10;
(*(x+1))[0] = 20;

答案 1 :(得分:2)

据我所能确定的那样,您的代码对于注释的期望是正确的,可以防止内存泄漏,并且没有未定义的行为,这一切都很好。

但是,请考虑一秒钟,您必须编写多少不必要的样板代码才能完成此工作。然后使用std::unique_ptr考虑以下代码,就行为而言,该代码与您的代码完全相同,但是通过使用自动处理该行为的类,删除了负责删除内存的样板:

#include<memory>

int main()
{
    auto x = std::make_unique<std::unique_ptr<int[]>[]>(20);
    x[0] = std::make_unique<int[]>(5); //x[0] ==>[0,0,0,0,0]
    x[1] = std::make_unique<int[]>(3); //x[1] ==>[0,0,0] 

    *x[0]     = 10; //x[0][0] = 10
    //This will no longer compile because, while technically correct, this kind of pointer arithmetic
    //is inherently unsafe and prone to mistakes
    //*(x+1)[0] = 20; //x[1][0] = 20
    x[1][0] = 20;

    cout << x[0][0] << endl;
    cout << x[1][0] << endl;

    //No more deletes needed; `std::unique_ptr` manages its own memory and deletes when needed

    return 0;
}

现在考虑下一个代码,该代码通过对动态大小的数组std::vector使用更健壮的惯用法来进一步简化:

#include<vector>

int main()
{
    std::vector<std::vector<int>> x(20);
    x[0].resize(5); //x[0] ==>[0,0,0,0,0]
    x[1].resize(3); //x[1] ==>[0,0,0] 

    x[0][0] = 10;
    x[1][0] = 20;

    cout << x[0][0] << endl;
    cout << x[1][0] << endl;

    return 0;
}

这是一个非常清楚的案例研究,为什么在大多数情况下,您应该偏爱std::unique_ptr<T[]>std::vector<T>之类的东西来描述“ T的数组”。对于二维数组std::unique_ptr<std::unique_ptr<T[]>[]>std::vector<std::vector<T>>,它们描述的语义与原始代码相同。

答案 2 :(得分:0)

唯一不正确的是,new int []不会初始化其成员。在*x=new int[5]之后,x可以为{123,456,789,-123,-456}或其他任何值。