2013-11-19 5 views
1

Просто читать это ТАК размещать stdshared-ptr-exception-safetyВозможно ли утечка памяти для размещения shared_ptr в куче?

Так следующий код не будет иметь утечку памяти:

std::shared_ptr<int> p3 (new int); 

Но как следующий:

func(new std::shared_ptr<int>(new int)); 

Если распределение shared_ptr броска bad_alloc исключение и «new int» был оценен, я предполагаю, что будет просочится int. Определяет ли они стандарт: new std::shared_ptr необходимо сначала выделить память, а затем оценить параметр new int?

+4

Каждый раз, когда вы говорите 'new' и не находитесь внутри конструктора умного указателя, у вас есть потенциальная утечка памяти. Просто не говори «новый». –

+0

Итак, будьте осторожны с 'new''s – user1095108

+1

Что говорит Керрек. Кроме того, почему на Земле вы бы выделили 'std :: shared_ptr' динамически? – Angew

ответ

0

Это может привести к утечке памяти, и это небезопасно. Выделенный std::shared_ptr должен быть где-то защищен. shared_ptr может выдать исключение, и вы должны его обработать. new std::shared_ptr также может генерировать исключение, и вы должны справиться с этим. Первое исключение не приводит к утечке памяти, а вторая доза.

С другой стороны, вам не нужно выделять std::shared_ptr динамически; он не имеет никаких преимуществ.

3

Да, это потенциальная утечка памяти.

Тем не менее, это очень нетрадиционное использование std::shared_ptr. Как правило, shared_ptr хранится в автоматическом хранилище (в стеке), чтобы воспользоваться RAII.

2

Да, это может привести к утечке.

Если new std::shared_ptr выбрасывается, нет ничего, чтобы очистить память, выделенную new int.

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

Для разработки, вы можете переписать код следующим образом:

// if 'new' throws, we just get a bad_alloc, nothing leaked 
int *iptr = new int; 

// if 'new' throws, nothing will clean up iptr 
// 
// if, for whatever reason, ctor of std::shared_ptr<int> throws, 
// its memory gets reclaimed by an implicit delete, but iptr's target 
// is still lost. 
auto *ptrptr = new std::shared_ptr<int>(iptr); 

// EDIT: If the constructor of shared_ptr fails, it will delete 
// the memory it is given, though this still doesn't eliminate the 
// leak that can occur if the above `new` fails. 

EDIT:

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

В последнем случае это действительно зависит от того, что делает конструктор типа с его аргументом. В случае std::shared_ptr, скорее всего, он не будет генерировать исключение, если ему не удастся выделить контрольный блок (если это фактически то, как оно реализовано).

Если конструктор std::shared_ptr терпит неудачу, по крайней мере, с реализацией я использую (VS2012), он на самом деле делает удаления памяти она дана.

2

Если распределение shared_ptr броска bad_alloc исключения и new int было оценить, я предполагаю, что int утечки.

Да, если оценки происходят в этом порядке, а выделение для общего указателя не удастся, тогда будет пропущено целое число.

ли они стандарт определил new std::shared_ptr необходимость первого выделения памяти, а затем вычислить параметр new int?

Нет, они неопределенно упорядочены, как указано в C++ 11 5.3.4/16.

Так динамическое распределение интеллектуальных указателей опасно, а не просто странно и запутанно. Не делай этого.

Смежные вопросы