【问题标题】:Proper initialization and destruction of a C++ array of object pointers? [duplicate]正确初始化和销毁​​ C++ 对象指针数组? [复制]
【发布时间】:2019-03-01 12:53:19
【问题描述】:

我想创建一个指向自定义对象 Image 的指针数组,但我不确定我是否做得正确(而且我对指针数组没有任何经验)。我有一个构造函数,它将一个图像作为第一个元素和数组大小,但我认为我没有正确创建图像指针数组。我知道这可能要容易得多,但我不想使用向量。

在头文件中,我有:

class Album {
public:
  unsigned arrmax;
  Image** imgar;
  Image basepic;

在 cpp 文件中我有一个构造函数:

Album::Album(const Image & picture, unsigned max) {
arrmax = max;
basepic = picture; //operator overloaded
imgar = new Image*[arrmax]; //array of Image pointers 
for (unsigned i = 0; i < max; i++) {
   imgar[i] = NULL;
  }
 imgar[0] = &basepic;
}

我的析构函数如下所示:

Album::~Album() {
if (imgar != NULL) {
for (unsigned i = 0; i < this->arrmax; i++) {
  if (imgar[i] != NULL) {
    delete imgar[i]; // delete[] or delete??
   } 
  }
 }
}

对于析构函数,在遍历元素后我是否也必须执行delete[] imgar?还是我只是没有删除正确的内容?

【问题讨论】:

  • 您可能想使用 std::vector&lt;std::vector&lt;std::unique_ptr&lt;Image&gt;&gt;&gt; 并完全忘记手动内存管理。
  • delete 你是什么newdelete[] 你是什么new[]。如果你既不是new 也不是new[],那么你就不是delete 也不是delete[]imgar[i] 是指向任何 basepic 的指针,你似乎没有 new 它。避免这些问题并使用智能指针,如std::unique_ptr 或标准容器。
  • 对不起,一个间接的太多了,std::vector&lt;std::unique_ptr&lt;Image&gt;&gt; 就足够了。
  • 您真正需要的很可能只是std::vector&lt;Image&gt;
  • 现代 c++ 程序通常不应该使用裸指针,使用 shared_ptr 或 unique_ptr。

标签: c++ arrays pointers constructor destructor


【解决方案1】:

您不需要析构函数中的 for 循环,因为您想删除使用 new [] 创建的指针数组。 仅此一项就足够了:

Album::~Album() {
    delete[] imgar;
}

【讨论】:

    【解决方案2】:

    根据您的问题,我了解到您更喜欢一些方向/良好做法,而不是直接回答。

    一些好的做法:

    • 尽量避免直接内存管理,这很容易出错。尽可能选择智能指针(唯一、共享、弱)
    • 您可以使用 std::array/std::vector 作为改进的数组,它管理大小并具有其他一些优点。
    • 对于数组大小,首选 size_t 而不是“unsigned int”
    • 大多数情况下,容器范围循环更具可读性和速度。

    所以你的代码可能是这样的:

    class Album{
    public:
        std::vector<std::unique_ptr<Image>> _imgVect;
        Image basepic;
        ...
    };
    
    Album::Album(const Image & picture, unsigned max) {
        _imgVect.reserve(max);
        basepic = picture; //operator overloaded
        // default of unique_ptr is already nullptr
    
        // Not really a good practice, but without more information
        // of what you are trying, it is the best I could imagine.
        _imgVect[0] = std::unique_ptr<Image>(&basepic, [](Image*){});
    }
    
    // Use default destructor
    

    但我不想使用向量

    有什么特别的原因吗?如果您不想要容器,可以:新建/删除是您的选择。您可能仍会使用智能指针。

    对于析构函数,我是否还必须在遍历元素后也执行 delete[] imgar?还是我只是没有删除正确的内容?

    使用delete[] 将删除数组,但不会删除为数组中每个指针保存的内容。在删除所有带有delete[] 的数组之前,您必须在每个元素上使用delete

    您必须非常小心删除的内容,例如,数组的第一个元素(在您的问题代码中)不是堆分配的对象,因此尝试删除它会产生未定义的行为(通常是崩溃) .

    【讨论】:

      猜你喜欢
      • 2012-11-30
      • 1970-01-01
      • 2012-10-27
      • 2014-03-14
      • 1970-01-01
      • 1970-01-01
      • 2019-12-05
      • 1970-01-01
      • 2013-06-30
      相关资源
      最近更新 更多