Утечка памяти - освободить и удалить

IFSUPCUTILSize* size = NULL;
CoCreateInstance(CLSID_UTILSize, NULL, CLSCTX_INPROC_SERVER, IID_IFSUPCUTILSize,    reinterpret_cast<void**>(&size));

if (size != NULL){
size->Release();
size = NULL;
}
delete size;

Нужно ли "удалить размер" в коде выше? Если я добавлю "delete size", у меня будет утечка памяти, потому что я не использовал New. Или есть новый внутри вызова CoCreateInsatnce. Я строю это с VC++ 6.

5 ответов

Решение

COM-интерфейсы подсчитываются. CoCreateInstance() возвращает указатель интерфейса на COM-объект, чей счетчик ссылок уже увеличен. призвание Release() уменьшает счетчик ссылок. Когда счетчик ссылок падает до нуля, COM-объект освобождается автоматически. Не звони delete на указателе интерфейса COM! Всегда используйте Release() только.

С точки зрения C++, то, что вы делаете, хорошо. Вызов delete для нулевого указателя не работает. Однако это не нужно.

С точки зрения VC++6, я не могу сказать, что он общеизвестно несовместим. Я не могу себе представить, почему это может быть проблемой, хотя. Но опять же, это, безусловно, не нужно.

Определенно не вызывайте delete для этого указателя, пока он не будет установлен в NULL. Вы не выделяете с новым, поэтому не вызывайте удалить. Об управлении ресурсами здесь заботятся функции COM.

Никогда не пытайтесь использовать delete освободить COM-серверы, реализованные другим модулем (это ваш случай).

  1. Вы не всегда знаете, написан ли этот сервер на C++. дела delete для не-C++ объекта неопределенное поведение.
  2. Даже если сервер написан на C++, вы не знаете, на какой куче он был размещен и delete правильно освободит память или вызовет неопределенное поведение.
  3. Ты звонишь delete на указателе интерфейса, который объявлен как не имеющий виртуального деструктора - это неопределенное поведение.
  4. Вы не всегда знаете, обслуживали ли вы реальный объект или доверенное лицо. дела delete на прокси есть неопределённое поведение.
  5. Однажды ты позвонил Release() объект может быть уже удален и делает delete опять неопределенное поведение.
  6. Кто-то другой мог бы стать владельцем объекта, например, для вашего объекта мог быть установлен экземпляр глобального указателя. если ты delete эти другие указатели станут висящими, и это, вероятно, вызовет неопределенное поведение позже.

Итог: не использовать delete в этом случае никогда. Вызов Release() освободить право собственности на объект, и этого будет достаточно.

Если я добавлю "delete size", у меня будет утечка памяти, потому что я не использовал New.

Вы обычно не получите утечку памяти, позвонив delete, Вы можете и много раз получите повреждение памяти. Они очень разные: утечка памяти означает, что ваша программа удерживает память, которую она на самом деле не использует, со временем программа может аварийно завершить работу, если утечка памяти продолжает расти; Повреждение памяти означает, что вы каким-то образом заточили важные структуры бухгалтерского учета в памяти и, вероятно, очень скоро рухнут (по крайней мере, вы должны надеяться на сбой, альтернатива хуже). Одна из наиболее распространенных причин повреждения памяти - освобождение памяти с неправильной процедурой, особенно в Windows (это традиция переопределять malloc а также free в UNIX, поэтому системы UNIX часто стараются изо всех сил, чтобы убедиться, что это возможно).

Или есть новый внутри звонка CoCreateInstance

Что бы ни было внутри CoCreateInstance должен быть обработан Release(), По крайней мере, вы никогда не должны освобождать память только потому, что у вас есть указатель. Вам нужно знать, как у них была выделена память, чтобы правильно ее освободить.

Я предполагаю, что size->Release() освобождает ресурсы ОС (дескрипторы файлов и т. Д.). Поэтому установите размер удаления сразу после того, как перед установкой размера на ноль.

Другие вопросы по тегам