【问题标题】:Correct way to delete a vector of pointers in C++在 C++ 中删除指针向量的正确方法
【发布时间】:2021-05-05 00:09:33
【问题描述】:

鉴于下一个剪辑:

vector<cv::Mat> list; // Hold the pointer values (not the pointers)

for (int index = 0; index < item_count; index++)
{
    jobject bitmap = env->GetObjectArrayElement(listBitmaps, index);

    // BitmapUtils::toMat returns a cv::Mat* which has been created with "new cv::Mat()"
    cv::Mat* mat = BitmapUtils::toMat(bitmap);

    list.push_back(*mat); // Store the object value
}

下一步是删除向量对象指针的正确方法吗?

for (auto entry : sources)
{
    delete & entry;
}

请注意,我不能使用指针向量,例如 vector<:mat>

【问题讨论】:

  • 什么是sources?我在您的代码中看不到 new。你为什么要delete什么的?不要delete 未分配new 的内存。
  • @AtahanAtay 将自动对象的地址传递给delete 永远不会正确。
  • “请注意,我不能使用诸如vector<:mat>之类的指针向量。” 为什么不呢? list.push_back(*mat);mat 指向的对象的副本推送到列表中。你不能delete它。将副本推送到list 后,也许您想delete mat
  • sources 向量中的内容无关紧要。它可以是任何东西的向量,并且显示的delete 实际上保证是完全错误的,并且由于至少两个独立的独立原因导致几乎可以保证的崩溃(entry 在自动范围内,向量成员是不是单独newed,即使他们是删除它的矢量作业,所以实际上有三个原因。
  • 如果您需要删除任何内容,请联系mat。该向量将包含副本,并将管理它自己的内存。

标签: c++ pointers vector


【解决方案1】:

“下一步是删除向量对象指针的正确方法吗?”不,不是。

如果sources 的类型为vector&lt;cv::Mat *&gt;,则必须将指针指向delete

for (auto entry : sources)
{
    delete entry;
}

向量vector&lt;cv::Mat&gt; list; 具有自动存储期限。它将在其块结束时自动销毁。它将为其元素分配和释放内存。您不能delete 向量或其元素。

如果你必须deletecv::Mat* mat = BitmapUtils::toMat(bitmap);返回的指针你可以这样做:

vector<cv::Mat> list; // Hold the pointer values

for (int index = 0; index < item_count; index++)
{
    jobject bitmap = env->GetObjectArrayElement(listBitmaps, index);

    // BitmapUtils::toMat returns a cv::Mat* which has been created with "new cv::Mat()"
    cv::Mat* mat = BitmapUtils::toMat(bitmap);

    list.push_back(*mat); // Store the object value
    delete mat;
}

【讨论】:

  • 元素的存储时间不是“自动”的。 Cppreference 称之为“分配的存储持续时间”。
  • @HolyBlackCat 但也列出了四种存储时长:en.cppreference.com/w/cpp/language/…
  • 我有一个疑问,因为 cv::Mat 已在堆中创建,因为它是使用 'new' 关键字创建的,如果我在推送到向量后立即删除作为您的示例,不会是垫子丢失了吗?我的意思是它不是从堆中删除的,因此即使在向量中也不再有效?
  • @API_1024 list.push_back(*mat); 推送副本。副本推送后可以deletemat
  • @HolyBlackCat 是的,这是错误的,因为我想强调不允许 delete 元素。我更改了段落。
【解决方案2】:

当 Vector 实例到达其作用域结束(生命周期结束)时,将调用其所有包含对象的析构函数。因此,如果您在向量中有对象(不是指向对象的指针),那么您不需要执行任何明确的删除调用,而不是计算对象的析构函数中的那个。

相反,如果向量中有指针,则需要对这些指针调用 delete,如果要释放它们的关联对象,请确保它们仍指向现有对象(即尚未被其他对象删除部分代码)。

最后,为了确保您没有内存泄漏,这始终是一个好主意,并建议使用 Valgrind 测试您的程序。

【讨论】:

    猜你喜欢
    • 2021-06-14
    • 2018-08-09
    • 2020-06-24
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    • 2013-07-02
    • 1970-01-01
    • 2010-09-08
    相关资源
    最近更新 更多