unique_ptr, qvector.resize() 抛出错误 2280 试图引用已删除的函数

Posted

技术标签:

【中文标题】unique_ptr, qvector.resize() 抛出错误 2280 试图引用已删除的函数【英文标题】:unique_ptr, qvector.resize() throws error 2280 attempting to reference a deleted function 【发布时间】:2018-01-12 10:03:19 【问题描述】:

为了防止范围蔓延(在 previous Q 上),我已经隔离了上述错误。

我的体素类定义:

#ifndef VOXEL_H
#define VOXEL_H

#include <QObject>
#include <QVector>
#include <iostream>
include <memory>

class Voxel : public QObject

    Q_OBJECT
public:
    Voxel();
    ~Voxel();
;

#endif // VOXEL_H

触发错误的主文件:

#include <voxel.h>

int main(int argc, char *argv[])

    QVector < QVector <std::unique_ptr <Voxel> > > cVoxel;

    cVoxel.resize(0);

    int rows = 80, cols = 80;

    for (int i = 0; i < rows; i++)
    
       cVoxel[i].resize(cols);
       for (int j = 0; j < cols; j++)
       
          cVoxel[i][j].reset(new Voxel);
       
    

最终抛出错误的行是:

cVoxel[i].resize(cols);

完整的错误跟踪:(这并不是说错误最终是主要的)

关于此错误还有其他问题 (that are helpful),但我无法完全理解如何解决它。似乎qvector.resize() 正在尝试重新分配并可能使用复制构造函数然后抛出此错误?我可以手动释放内存而不是使用上述函数,但使用智能指针的整体理想是避免内存泄漏......我开始使用 unique_ptr 来解决大量泄漏问题。


我使用的是 QtCreator 4.4.0 和 Qt 5.6.2,64 位。

--- 编辑---

如果我用std::vector替换QVector,即cVoxel创建为:

std::vector < std::vector <std::unique_ptr <Voxel> > > cVoxel;

然后程序在外部for循环中崩溃,在:

cVoxel[i].resize(cols);

调试表明:

调试断言失败!

程序:C:\windows\system32\MSVCP140D.dll 文件:C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\vector 线路:1234

表达式:向量下标超出范围

有关您的程序如何导致断言的信息 失败,请参阅有关断言的 Visual C++ 文档。

我可以通过将 cVoxel 的大小调整为 80 而不是 0 来使代码工作。但 QVector.resize()std::vector.resize() 的操作方式之间似乎存在细微差别。阅读每个人的文档,他们似乎都一样。

【问题讨论】:

使用 std::vector 代替 QVector。 我在我的独立项目上尝试过:链接器错误 (doh)。但是,在我的实际项目中,该项目运行并在崩溃前读取图像。这是向前迈出的一步,我打赌崩溃是我的错,而不是 std::vectorstd::unique_ptr :-) 谢谢! 【参考方案1】:

unique_ptr 无法复制(只能移动或移动分配):

类 (unique_ptr) 满足 MoveConstructible 和 MoveAssignable,但不是 CopyConstructible 的要求 或 CopyAssignable。

复制构造函数和复制分配在unique_ptr 中被删除,因此出现错误。 cVoxel[i].resize(cols) 隐式要求复制。 您可以使用QVector&lt;QVector&lt;Voxel&gt;&gt; 作为替代方案。

另一件事:在cVoxel.resize(0) 之后调用cVoxel[i].resize(cols) 是越界的。你可能需要cVoxel.resize(rows)

【讨论】:

据我所知,这是错误的根源。为了后代,我避免在我的项目中使用智能指针(改为手动修复最明显的泄漏)。这是因为预算/时间限制。不过,我肯定会在未来任何类似范围的编程项目中使用智能指针。

以上是关于unique_ptr, qvector.resize() 抛出错误 2280 试图引用已删除的函数的主要内容,如果未能解决你的问题,请参考以下文章

智能指针unique_ptr用法

智能指针之unique_ptr

unique_ptr 到派生类作为函数的参数,该函数将 unique_ptr 带到基类

C++ unique_ptr介绍及仿写

智能指针unique_ptr记录

C++ 11 创建和使用 unique_ptr