C ++ освобождает статические переменные - PullRequest
24 голосов
/ 12 марта 2010

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

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

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

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

Спасибо, JBU

Ответы [ 5 ]

19 голосов
/ 12 марта 2010

У вас есть два решения здесь:

  1. Не удаляйте, удаляйте его (вы находитесь в C ++, вы используете new и delete, верно?;)). Почти все операционные системы сегодня "освободят" память, выделенную приложению, так или иначе, как только оно будет завершено. Но это не очень хорошее решение, которое затрудняет обнаружение утечек памяти, например.
  2. Инкапсулируйте ваш указатель в класс (как член) , затем используйте этот класс в качестве типа вашей статики. Таким образом, вы знаете, что деструктор класса будет вызван в конце приложения. Затем вы просто удаляете свои данные в деструкторе, и работа сделана и очищена. Это сила 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's 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() 

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

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

16 голосов
/ 12 марта 2010

Киньте в умный указатель. Он будет иметь статическое время жизни и будет уничтожен после того, как 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;
}

Который будет иметь тот же эффект. Другой вариант, который вы уже упомянули, - это сохранение статического счетчика. Заметьте, что вы можете довольно эффективно это обернуть.

7 голосов
/ 12 марта 2010

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

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

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

2 голосов
/ 12 марта 2010

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

0 голосов
/ 12 марта 2010

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

...