Будет ниже утечки памяти причины кода в C++

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
18
задан 9 revs, 3 users 48% 27 August 2013 в 09:53
поделиться

6 ответов

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

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

, Если Вы используете что-то как scoped_ptr< Повышения;> шаблон, Ваш класс мог посмотреть больше как:

class base{
    int a;
    scoped_ptr<int> pint;
    someclass objsomeclass;
    scoped_ptr<someclass> psomeclass;
    base() : 
       pint( new int),
       objsomeclass( someclass()),
       psomeclass( new someclass())

    {
        throw "constructor failed";
        a = 43;
    }
}

И у Вас не было бы утечек памяти (и значение по умолчанию dtor также очистит динамические выделения памяти).

<час>

Для подведения (и надо надеяться это также отвечает на вопрос о

base* temp = new base();

оператор):

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

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

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

  1. ловят исключение, высвобождают средства, затем повторно бросают. Это может быть трудно стать корректным и может стать проблемой обслуживания.
  2. использование возражает, чтобы управлять временем жизни ресурса (RAII) и использовать те объекты в качестве участников. Когда конструктор для Вашего объекта выдаст исключение, членским объектам назовут деструкторы и будут иметь возможность освободить ресурс, за время жизни которого они ответственны.
36
ответ дан 30 November 2019 в 07:23
поделиться

Оба new's будут пропущены.

Присваивают адрес созданных объектов "кучи" к [1 115] названный интеллектуальные указатели так, чтобы он был удален в деструкторе интеллектуальных указателей, которые получают вызов, когда исключение выдается - ( RAII).

class base {
    int a;
    boost::shared_ptr<int> pint;
    someclass objsomeclass;
    boost::shared_ptr<someclass> psomeclass;

    base() :
        objsomeclass( someclass() ),
        boost::shared_ptr<someclass> psomeclass( new someclass() ),
        boost::shared_ptr<int> pint( new int() )
    {
        throw "constructor failed";
        a = 43;
    }
};

Теперь psomeclass & пинта деструкторы назовут, когда стек раскрутится, когда исключение будет выдано в конструкторе, и те деструкторы освободят выделенную память.

int main(){
    base *temp = new base();
}

Для обычного выделения памяти с помощью (non-plcaement) новый, память, выделенная новым оператором, освобождена автоматически, если конструктор выдает исключение. С точки зрения того, почему беспокойство, освобождая отдельных участников (в ответ на комментарии к ответу B Mike), только применяется автоматическое освобождение, когда исключение выдается в конструкторе объекта, являющегося new'ly выделенный, не в других случаях. Кроме того, память, которая освобождена, является выделенными для элементов объекта, не любая память, которую Вы, возможно, выделили, говорит в конструкторе. т.е. Это освободило бы память для членских переменных , пинта , objsomeclass, и psomeclass, но не память, выделенная от новый someclass () и новый интервал () .

5
ответ дан 30 November 2019 в 07:23
поделиться

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

0
ответ дан 30 November 2019 в 07:23
поделиться

Да, тот код пропустит память. Блоки памяти, выделенной с помощью "нового", не освобождены, когда исключение повышено. Это - часть мотивации позади RAII.

Для предотвращения утечки памяти попробуйте что-то вроде этого:

psomeclass = NULL;
pint = NULL;
/* So on for any pointers you allocate */

try {
    objsomeclass = someclass();
    psomeclass = new someclass();
    pint = new int(); 
    throw "constructor failed";
    a = 43;
 }
 catch (...)
 {
     delete psomeclass;
     delete pint;
     throw;
 }
<час>
0
ответ дан 30 November 2019 в 07:23
поделиться

Все Вы "новые" потребности, которые будут удалены, или Вы вызовете утечку памяти. Так эти две строки:

psomeclass = new someclass();
pint = new int(); 

вызовет утечки памяти, потому что необходимо сделать:

delete pint;
delete psomeclass;

В наконец блоке для предотвращения их пропускаемый.

кроме того, эта строка:

base temp = base();

Является ненужным. Просто необходимо сделать:

base temp;

Добавление "= основа ()" является ненужной.

-2
ответ дан 30 November 2019 в 07:23
поделиться

необходимо удалить psomeclass... Не необходимый для чистки целого числа...

RWendi

-3
ответ дан 30 November 2019 в 07:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: