问题
To prevent scope creep (on a previous Q), I've isolated the above error.
My Voxel class definition:
#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
The main file which triggers the error:
#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);
}
}
}
The line ultimately throwing the error is:
cVoxel[i].resize(cols);
The full error trace: (which doesn't say that the error ultimately comes main)
There are other Questions (that are helpful) about this error but I can't fully understand how to resolve it. It would seem that qvector.resize()
is attempting to reallocate and likely using a copy constructor which is then throwing this error? I could manually free the memory instead of using the above function, but the whole ideal of using smart pointers is to avoid memory leaks... I started using unique_ptr to address substantial leaking.
I'm using QtCreator 4.4.0 and Qt 5.6.2, 64-bits.
--- EDIT ---
If I replace QVector
with std::vector
, ie cVoxel is created as:
std::vector < std::vector <std::unique_ptr <Voxel> > > cVoxel;
Then the program crashes in the outer for loop, at:
cVoxel[i].resize(cols);
Debugging reveals that:
Debug Assertion Failed!
Program: C:\windows\system32\MSVCP140D.dll File: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\vector Line: 1234
Expression: vector subscript out of range
For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.
I can get the code to work by resizing cVoxel to 80 rather than 0. But it appears there's a subtle difference between how QVector.resize() and std::vector.resize() operate. Reading the docs for each, they seemed identical.
回答1:
unique_ptr cannot be copied (only moved or move-assigned):
The class (
unique_ptr
) satisfies the requirements of MoveConstructible and MoveAssignable, but not the requirements of either CopyConstructible or CopyAssignable.
The copy-constructor and copy-assignment are deleted in unique_ptr
hence the error. Copying is implicitly required by cVoxel[i].resize(cols)
.
You could use QVector<QVector<Voxel>>
as an alternative.
Another thing: calling cVoxel[i].resize(cols)
after cVoxel.resize(0)
is out-of-bounds. You probably need cVoxel.resize(rows)
.
来源:https://stackoverflow.com/questions/48223804/unique-ptr-qvector-resize-throws-error-2280-attempting-to-reference-a-deleted