Подтвердить что ты не робот

С++ освобождение статических переменных

Я хотел бы, чтобы мой класс имел статический указатель на динамически выделенную область памяти. Я понимаю, как его инициализировать - в моем случае я инициализирую его, когда ему нужен первый объект. Тем не менее, я не знаю, когда/где в коде, чтобы освободить его. Я хотел бы освободить его, когда программа завершается.

Я мог бы освободить указатель в деструкторе моих объектов, но тогда мне пришлось бы поддерживать подсчет объекта, чтобы убедиться, что он свободен, когда объект является последним используемым объектом.

Есть ли более элегантный способ сделать это?

Пожалуйста, дайте мне знать.

Спасибо, JBU

4b9b3361

Ответ 1

Здесь у вас есть два решения:

  • Не удалять его удалить (вы на С++, вы используете новые и удаляете, правильно?;)). Почти все ОС сегодня будут "освобождать" память, выделенную приложением, как только она закончится. Но это не очень хорошее решение, затрудняющее обнаружение утечек памяти, например.
  • Инкапсулируйте указатель в класс (как член), затем используйте этот класс в качестве типа вашего статического. Таким образом, вы знаете, что деструктор класса будет вызван в конце приложения. Затем вы просто удаляете свои данные в деструкторе, и работа выполняется и очищается. Это сила RAII.

Я предлагаю вам сделать 2, это действительно чистый способ сделать это.


Вот простой пример. Вместо этого

static Thing* things = new Thing(); // or whatever way to initialize, here or in a specific function

Вы сделаете это:

class ThingManager // or whatever name you like
{
public:
   ThingManager( Thing* thing ) : m_thing( thing ) { }//or create it here? whatever solution suits your way of creating the data

   ~ThingManager() { delete m_thing; } // THAT the important part!

    Thing* instance() const { return m_thing; } // or whatever accessor you need, if you need one

private:
    Thing* m_thing;
};

а затем

static ManagedThing thing; // now i can access it via thing.instance() 

Когда программа закончится, статическая переменная (которая больше не указана) будет уничтожена, и для ее вызова будет вызван деструктор.

Он написан только для того, чтобы дать вам представление о том, как вы можете это сделать.

Ответ 2

Бросьте его в умный указатель. Он будет иметь статическое время жизни и будет уничтожен после возврата main:

static std::auto_ptr<T> thePointer;

Другой вариант - зарегистрировать свою собственную функцию atexit:

// static
void YourClass::freePointer(void)
{
    delete getPointer();
}

// static
T* YourClass::getPointer(void)
{
    if (!thePointer)
    {
        thePointer = new T;
        atexit(freePointer);
    }

    return thePointer;
}

Что будет иметь тот же эффект. Еще один вариант, который вы уже упоминаете, - сохранить статический счетчик. Обратите внимание, что вы действительно можете эффективно обернуть это.

Ответ 3

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

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

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

Ответ 4

Вы можете объявить статическую переменную умным указателем, а затем, когда программа завершит выделение указателя, будет освобождена.

Ответ 5

я бы определил статический счетчик в классе для отслеживания количества экземпляров объектов поскольку деструктор получает выполнение, он уменьшает счетчик, и если счетчик == 0 освобождает память тоже.. так же, как вы