Как я могу очистить после синглтона в C ?

#design-patterns #visual-c #memory-leaks

#шаблоны проектирования #visual-c #утечки памяти

Вопрос:

Следующая тривиальная демонстрация записывает «утечку памяти: 8» на консоль, для меня.
Если я закомментирую строку getInstance() в main(), он пишет «утечка памяти: 0».
Еще более странно, если я закомментирую строку «void * dummy = nullptr;» в TestSingleton, я получаю «утечка памяти: 1».

Что в мире происходит?

Здесь происходит только одно выделение кучи, и оно удаляется. Итак, как это происходит утечка?

 #include <iostream>

#include <crtdbg.h>
#include <conio.h>

struct TestSingleton
{
    static TestSingleton * instance;    
    void* dummy = nullptr;

    static TestSingleton amp; GetInstance()
    {
        if (!instance) instance = new TestSingleton();
        return *instance;
    }

    static void Destroy()
    {
        delete instance;
        instance = nullptr;
    }
};

TestSingleton* TestSingleton::instance = nullptr;

int main()
{
    _CrtMemState state1;
    _CrtMemState state2;
    _CrtMemState state3;

    _CrtMemCheckpoint(amp;state1);

    {
        TestSingletonamp; t = TestSingleton::GetInstance();
        TestSingleton::Destroy();
    }

    _CrtMemCheckpoint(amp;state2);
    _CrtMemDifference(amp;state3, amp;state1, amp;state2);
    size_t difference = state3.lTotalCount;

    std::cout << "memory leak: " << difference << "n";

    char dmy = getchar();
    return 0;
}
  

Комментарии:

1. Я могу объяснить получение 1 : размер экземпляра пустого класса (без членов) не может быть равен 0. Я думаю, это зависит от компилятора, и MS использует 1 . An 8 — это размер указателя void в 64-разрядной сборке.

2. Но я удаляю экземпляр. Не должно быть никакого экземпляра. И статический указатель на экземпляр существовал до первой контрольной точки кучи. Он должен быть загружен с помощью nullptr перед запуском любого кода.

Ответ №1:

Я думаю, что я понял это, или, по крайней мере, я обнаружил подсказку. При связывании с средой выполнения отладки из-за настроек проекта, связанных с библиотеками, с которыми я связываюсь, я в конечном итоге получаю CrtDbgFlag, установленный таким образом, что выделения не освобождаются. Проблема исчезает после сборки в режиме выпуска, и она исчезает в режиме отладки, если я вызываю _CrtSetDbgFlag(0) перед выделением и освобождением.

Если я делаю что-либо из этого, эта программа сообщает «утечка памяти: 0».

Комментарии:

1. О нет, но теперь он делает это снова в режиме отладки, установки CrtDbgFlag в 0 недостаточно.