Выпуск C ++ против отладки, выделения памяти, пропущенные конструкторы - PullRequest
0 голосов
/ 17 декабря 2011

Это продолжение моего последнего вопроса: Полный сбой системы на C ++, только в режиме выпуска

В основном у меня есть древовидная структура данных, которая в режиме Release полностью зависаетОС.Это происходит из-за внезапного скачка в распределении памяти, который выходит за рамки возможностей ОС.

Эта кажущаяся утечка памяти (которая есть, но об этом через минуту) очень странная, потому что у меня есть всенеобходимый код для инициализации указателей в NULL и в конечном итоге для их выделения (при необходимости), если они окажутся равными NULL.В режиме отладки это правильное поведение подтверждается, и все распределяется нормально (я вижу, что указатели NULL установлены в ноль от отладчика).

Но в режиме выпуска все по-другому.Конструкторы полностью пропускаются, и все внутренние компоненты класса инициализируются случайным мусором.Это также приводит к тому, что указатели становятся бесполезными, и именно здесь выделяется память до тех пор, пока вся система не выйдет из строя.

Почему режим Release игнорирует мои конструкторы?

Я использую Visual Studio 2010 наКстати, Windows 7

Ответы [ 2 ]

5 голосов
/ 17 декабря 2011

Судя по (неполному) коду:

template <class NodeData> struct OctNode {
        OctNode() {
                for (int i = 0; i < 8; ++i)
                        children[i] = NULL;
        }
        ~OctNode() {
                for (int i = 0; i < 8; ++i)
                        delete children[i];
        }
        OctNode *children[8];
        vector<NodeData> data;
};

Может произойти утечка памяти при назначении OctNode другому. Компилятор генерирует конструктор копирования по умолчанию и оператор присваивания. Последнее может привести к утечкам памяти, поскольку не освобождает ранее выделенную память. Я предлагаю изменить определение класса следующим образом:

template <class NodeData> struct OctNode {
        OctNode() : children() {} // zero-initialize children
        ~OctNode() {
                for (int i = 0; i < 8; ++i)
                        delete children[i];
        }
        OctNode *children[8];
        vector<NodeData> data;
    private:
        OctNode(OctNode const&);
        OctNode& operator=(OctNode const&);
};

И компилирование вашего кода. Если он не компилируется из-за того, что OctNode& operator=(OctNode const&) является приватным, то это стало причиной утечки.

3 голосов
/ 17 декабря 2011

Код примера, на который вы указали (http://www.cmlab.csie.ntu.edu.tw/~wildmb/pbrt/octree_8h-source.html), имеет класс struct OctNode, управляющий необработанными указателями без соответствующего конструктора копирования или оператора присваивания (или отключив их).

class Octree содержит экземпляр struct OctNode, поэтому, если у вас есть Octree копируемые / назначаемые объекты, есть большая вероятность, что куча будет повреждена.

Добавьте следующее к struct OctNode, чтобы отключить копирование и назначение и посмотреть, начинаете ли вы получать ошибки компоновщика:

private:
    OctNode(const OctNode&);
    OctNode& operator=(const OctNode&);

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

...