Утечка памяти - освободить и удалить - PullRequest
4 голосов
/ 25 августа 2011
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 ]

10 голосов
/ 26 августа 2011

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

4 голосов
/ 25 августа 2011

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

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

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

1 голос
/ 26 августа 2011

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

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

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

0 голосов
/ 26 августа 2011

Если я добавлю «delete size», произойдет ли утечка памяти из-за того, что я не использовал New.

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

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

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

0 голосов
/ 25 августа 2011

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

...