Ошибка компилятора "компилятору не хватает места в куче" при вызове оператора `delete` в деструкторе - PullRequest
0 голосов
/ 29 июня 2018

Я написал класс с именем " TreeContainer ". Моя цель - спроектировать древовидный контейнер, который хранит содержимое в древовидной иерархии. Каждый контейнер дерева должен работать как папка / каталог в файловой системе. Папка (дерево) может иметь подпапки (поддеревья) и другие файлы (подпункты).

Я включил его в другой исходный файл, скажем, его имя " TreeUser.cpp ". Когда я пытаюсь отладить / запустить мой проект, Visual Studio компилирует исходные файлы проекта один за другим, и я вижу, какой файл в настоящее время компилируется на панели «Вывод» среды IDE. Когда дело доходит до файла TreeUser.cpp , он занимает СЛИШКОМ МНОГО времени. И, наконец, это приводит к фатальной ошибке ниже, и компиляция останавливается.

Ошибка: компилятору C1060 не хватает места в куче
[ Название проекта здесь ]
[ Путь к установке Visual Studio здесь * ] \ visual studio \ vc \ tools \ msvc \ 14.14.26428 \ include \ xmemory0 962

Код класса ниже.

TreeContainer.cpp

#pragma once

#include <vector>

template <class T>
class TreeContainer
{
    public:
        using SubTreeContainerType = std::vector<TreeContainer<T *> *>;
        using SubItemContainerType = std::vector<T *>;

        TreeContainer();
        ~TreeContainer();

        // ... (Lots of member functions here. Removing or keeping them has no effect.)

    private:
        SubTreeContainerType SubTrees;
        SubItemContainerType SubItems;

};

template <class T>
TreeContainer<T>::TreeContainer()
    : SubTrees(), SubItems()
{
}

template <class T>
TreeContainer<T>::~TreeContainer()
{
    for (typename SubTreeContainerType::iterator it=SubTrees.begin(); it!=SubTrees.end(); ++it)
    {
        //delete *it; (I get the error when I uncomment this line.)
    }
    for (typename SubItemContainerType::iterator it=SubItems.begin(); it!=SubItems.end(); ++it)
    {
        delete *it;
    }
}

После многих испытаний я понял, что проблема в линии деструктора. Удаление этого снимает проблему. Но мне нужна эта строка, чтобы очистить память.

В этой строке я вызываю оператор delete для содержимого контейнера SubTrees. Предполагается рекурсивно вызывать деструкторы на каждом поддереве. Я что-то здесь не так делаю или это ошибка в Visual Studio.

Версия IDE: Visual Studio Community 2017 15.7.4

Параметры командной строки:

/ permissive- / GS / W3 / wd "4290" / wd "5040" / Zc: wchar_t / ZI / Gm- / Od / sdl /Fd"x64\Debug\vc141.pdb "/ Zc: inline / fp : точный / D "SC_DEBUG" / D "_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING" / D "_UNICODE" / D "UNICODE" / errorReport: prompt / WX- / Zc: forScope / RTC1 / Gd / MDd / std: c ++ "x64 \ Debug \" / EHsc / nologo / Fo "x64 \ Debug \" / Fp "x64 \ Debug \ Project Name.pch" / диагностика: классическая

1 Ответ

0 голосов
/ 29 июня 2018

Похоже, вы создаете бесконечно много классов из вашего шаблона, потому что SubTreeContainerType из TreeContainer<T> ссылается TreeContainer<T *> (контейнер T указателей).

И деструктору нужен деструктор вектора поддеревьев, который, в свою очередь, нуждается в деструкторе TreeContainer<T *>, который нуждается в деструкторе TreeContainer<T **> и т. Д. С.

Решение:

using SubTreeContainerType = std::vector<TreeContainer<T> *>;

Или, если вы действительно хотите, чтобы контейнер поддеревьев ссылался на указатели на T, добавьте специализацию шаблона для указателей, которая нарушает рекурсию перед реализацией методов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...