Утечка памяти - освободить и удалить
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-серверы, реализованные другим модулем (это ваш случай).
- Вы не всегда знаете, написан ли этот сервер на C++. дела
delete
для не-C++ объекта неопределенное поведение. - Даже если сервер написан на C++, вы не знаете, на какой куче он был размещен и
delete
правильно освободит память или вызовет неопределенное поведение. - Ты звонишь
delete
на указателе интерфейса, который объявлен как не имеющий виртуального деструктора - это неопределенное поведение. - Вы не всегда знаете, обслуживали ли вы реальный объект или доверенное лицо. дела
delete
на прокси есть неопределённое поведение. - Однажды ты позвонил
Release()
объект может быть уже удален и делаетdelete
опять неопределенное поведение. - Кто-то другой мог бы стать владельцем объекта, например, для вашего объекта мог быть установлен экземпляр глобального указателя. если ты
delete
эти другие указатели станут висящими, и это, вероятно, вызовет неопределенное поведение позже.
Итог: не использовать delete
в этом случае никогда. Вызов Release()
освободить право собственности на объект, и этого будет достаточно.
Если я добавлю "delete size", у меня будет утечка памяти, потому что я не использовал New.
Вы обычно не получите утечку памяти, позвонив delete
, Вы можете и много раз получите повреждение памяти. Они очень разные: утечка памяти означает, что ваша программа удерживает память, которую она на самом деле не использует, со временем программа может аварийно завершить работу, если утечка памяти продолжает расти; Повреждение памяти означает, что вы каким-то образом заточили важные структуры бухгалтерского учета в памяти и, вероятно, очень скоро рухнут (по крайней мере, вы должны надеяться на сбой, альтернатива хуже). Одна из наиболее распространенных причин повреждения памяти - освобождение памяти с неправильной процедурой, особенно в Windows (это традиция переопределять malloc
а также free
в UNIX, поэтому системы UNIX часто стараются изо всех сил, чтобы убедиться, что это возможно).
Или есть новый внутри звонка CoCreateInstance
Что бы ни было внутри CoCreateInstance
должен быть обработан Release()
, По крайней мере, вы никогда не должны освобождать память только потому, что у вас есть указатель. Вам нужно знать, как у них была выделена память, чтобы правильно ее освободить.
Я предполагаю, что size->Release() освобождает ресурсы ОС (дескрипторы файлов и т. Д.). Поэтому установите размер удаления сразу после того, как перед установкой размера на ноль.