用于动态分配智能指针的2D数组的语法

时间:2013-03-18 22:51:53

标签: c++ arrays memory-management multidimensional-array smart-pointers

我需要动态分配一个智能指针的二维数组,但它的语法令我感到困惑。我需要这个是动态的:

std::unique_ptr<someClass> myArray[size1][size2];

所以根据我的理解,我创建了一个指向类型指针的指针:

someClass** myArray; //actaully the type is std::unique_ptr<someClass> but I'll just keep it simple

然后我分配它:

myArray* = new someClass*[size1];
for(int i = 0; i < size1; i++)
    myArray[i] = new someClass[size2];

但是这不使用智能指针,这意味着我将不得不在以后手动删除它,而且我不知道如何使这些指针成为智能指针;

类型是std :: unique_ptr但是我需要一个指向该类型的指针,所以我试过了:

std::unique_ptr<std::unique_ptr<std::unique_ptr<someClass>>> myArray;

但在此之后,我迷失了如何分配它。有人可以帮帮我吗?

2 个答案:

答案 0 :(得分:3)

我将向您展示如何具体解决您的问题,以及如何处理这样的问题。

一般情况下,就像任何过于复杂的问题一样,尝试将其分解。用于在C和C ++中分解复杂类型声明的工具长期以来一直是“typedef”。下面是如何处理类似于您所拥有的级联类型定义:采用最里面的包装类型,即包装类的unique_ptr,并为要包装的类型创建一个typedef。然后,继续对该类型包装的类型执行相同操作,直到您处于最外层类型。

这与您的问题仅相关,但我想提及它,因为您可能会遇到类似的问题,就像您现在使用的模板一样。从C ++ 11开始,您可以更方便地为涉及带有“using”子句的模板参数的类型定义别名:http://en.cppreference.com/w/cpp/language/type_alias。如果在这种情况下您感兴趣或在将来变得相关,请查看该链接!

针对您的具体问题。函数“test_dynamic_2darray1”构建了一个二维10x10智能指针数组。当您运行此代码时,您应该看到析构函数输出的100行,就在托管数组超出范围时。

size_t destructor_count = 0;
class MyClass {
    public:
    ~MyClass() {
        std::cout << "Destructor call #" << ++destructor_count << std::endl;
    }
};

typedef std::unique_ptr<MyClass[]> ManagedC;

void test_dynamic_2darray1() {
    size_t dimension1 = 10, dimension2 = 10;

    auto managed_array = std::unique_ptr<ManagedC[]>(new ManagedC[dimension1]);
    for (size_t i = 0; i < dimension1; ++i)
        managed_array[i] = ManagedC(new MyClass[dimension2]);
}

将此与此代码进行比较,其中不会调用动态分配的类实例的析构函数,并且您看不到输出:

void test_dynamic_2darray2() {
    size_t dimension1 = 10, dimension2 = 10;

    auto simple_array = new MyClass*[dimension1];
    for (size_t i = 0; i < dimension1; ++i)
        simple_array[i] = new MyClass[dimension2];
}

我希望我能够回答你的问题! :)如果你想让我详细说明,请告诉我!前几天我还写了一篇你可能感兴趣的相关博客文章:http://frankriesecodingblog.blogspot.com/2015/01/performance-of-dynamic-multi.html。我在这里发布它,因为它显示了多维动态数组的不同方法,并研究了使用向量矢量的常用方法的性能。

最后但同样重要的是,让我提一下你使用int迭代数组。我希望这不会变成我的宠儿,但我看到这已经做了很多。你应该使用size_t。为什么?例如,在我的64位机器上,“int”是32位,但是由size_t表示的地址是64位。这种误用int是造成许多错误的原因,特别是将32位应用程序移植到64位机器上。如果你需要一个有符号的类型,对于诸如数组地址之间的偏移之类的用途,更好的用途可能是ptrdiff_t。

答案 1 :(得分:2)

作为一个说明性示例,下面是可以在C ++现代中使用的语法,用于使用智能指针(unique_ptr)创建和填充2D int数组(大小为3乘5)以及其他功能,例如{ {1}}和make_unique

move()