unique_ptr, qvector.resize() выдает ошибку 2280 при попытке ссылки на удаленную функцию

Чтобы предотвратить ползучесть области (на предыдущем Q), я изолировал вышеупомянутую ошибку.

Мое определение класса Voxel:

#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);

Полная трассировка ошибок: (которая не говорит о том, что ошибка в конечном итоге становится основной)

введите описание изображения здесь

Есть и другие вопросы ( которые полезны) об этой ошибке, но я не могу полностью понять, как ее устранить. Казалось бы, что qvector.resize() пытается перераспределить и, вероятно, использовать конструктор копирования, который затем выдает эту ошибку? Я мог бы вручную освободить память вместо использования вышеупомянутой функции, но весь идеал использования умных указателей - избегать утечек памяти... Я начал использовать unique_ptr для устранения существенной утечки.


Я использую QtCreator 4.4.0 и Qt 5.6.2, 64-битные.

--- РЕДАКТИРОВАТЬ ---

Если я заменю QVector с std::vector т.е. 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() работать. Читая документы для каждого, они казались идентичными.

1 ответ

Решение

unique_ptr не может быть скопировано (только перемещено или назначено для перемещения):

Класс (unique_ptr) удовлетворяет требованиям MoveConstructible и MoveAssignable, но не требованиям CopyConstructible или CopyAssignable.

Конструктор копирования и назначение копирования удаляются в unique_ptr отсюда и ошибка. Копирование неявно требуется cVoxel[i].resize(cols), Вы могли бы использовать QVector<QVector<Voxel>> как альтернатива.

Другое дело: звонить cVoxel[i].resize(cols) после cVoxel.resize(0) выходит за пределы. Вам наверное нужно cVoxel.resize(rows),

Другие вопросы по тегам