LINUX.ORG.RU

public int и дестрактор


0

0

Никак не догоню, как правильно освободить память в которой лежал объект навроде

class A {
   A();
   ~A();
   int a;
   int* b;
};

A::A() {
   a = 0;
   b = new int;
}

A::~A {
   delete b;
   (как убить a?)
}

если пишу delete &a, получается segmentation fault.
anonymous

Ответ на: комментарий от dilmah

фигасе релакс

LEAK SUMMARY: ==7875== definitely lost: 1,200 bytes in 40 blocks.

у меня память не казённая

anonymous
()

фубля ступил

anonymous
()

Не нужно с этим а ничего делать.

smh ★★★
()

Освобождать не требуется, сама уйдет после вызова деструктора этого класса. А память течет где-то в другом месте.

Deleted
()

У класса A два поля: a и b.

При выделении памяти под A выделяется память под int a и указатель на int b.

Где-то внутри, например в конструкторе, класс A скорее всего выделяет память под массив int и запоминает указатель на него в этот int *b.

В деструкторе освобождается память, выделенную под массив, на которую показывает b, а память, выделенную под a и b освобождается при освобождении памяти, выделенной под экземпляр A.

Ясно? :)

(Переходили бы уже на языки с автоматическим управлением памятью...)

naryl ★★★★★
()
Ответ на: комментарий от anonymous

> а может стоит > int *b = NULL; > if(b) delete b; > а то может плохо кончиться

бегом читать стандарт зи-блюз-блюз

grob ★★★★★
()

Вы б книжки какие почитали...

svu ★★★★★
()
Ответ на: комментарий от anonymous

В последнем стандарте new не возвращает null, теперь там надо ексепшен ловить ;) так что if(b) чаще всего беспоезно (не считая дремучих компиляторов).

Cy6erBr4in ★★★
()
Ответ на: комментарий от Cy6erBr4in

Да и это не говорит не о чём, сейчас нельзя проврят выделилась ли
память или нет, тупой проверкой на ноль

типа

int *a = new int[10];

if (!a) cout << "Error!!!" << endl;

в современных компиляторах не получишь ты там null никак, тоесть в
принципе, если конечно не напишешь так:

int *a = new(nothrow) int [10];

опять же зависит от компилятора...

и если компилятор нормальный, то проверять выделение памяти надо так:

int *a;

try
{
a = new int[10];
}
catch (bad_alloc ex)
{
cout << "Error!!!" << endl;
return 1;
}

вот как-то так (в старых компиляторах данный код с исключительными ситуациями работать не будет).

Cy6erBr4in ★★★
()
Ответ на: комментарий от Cy6erBr4in

> Всё зависит от реализации конкретного компилятора, я бы не стал полагаться на "авось".

Это прописано в стандарте.

> Да и это не говорит не о чём, сейчас нельзя проврят выделилась ли память или нет, тупой проверкой на ноль

Речь идёт про delete а не про new.

> и если компилятор нормальный, то проверять выделение памяти надо так:

int *a;

try { a = new int[10]; } catch (bad_alloc ex) { cout << "Error!!!" << endl; return 1; }

Простите, вы на С++ только в университете писали? По-моему ловить исключение по ссылке - это спинно-мозговой рефлекс любого С++-программиста. Да и использовать монструозный iostream в условиях нехватки памяти, не самое умное решение. Уж лучше write или fputs, если не POSIX-ы нужны.

anonymous
()
Ответ на: комментарий от anonymous

>> Всё зависит от реализации конкретного компилятора, я бы не стал полагаться на "авось".

> Это прописано в стандарте.

и что? все без исключения придерживаются стандартов? не смешите... (не говорю про конкретно этот случай с delete, а в общем...)

>> и если компилятор нормальный, то проверять выделение памяти надо так:

> int *a;

> try { a = new int[10]; } catch (bad_alloc ex) { cout << "Error!!!" << endl; return 1; }

> Простите, вы на С++ только в университете писали? По-моему ловить исключение по ссылке - это спинно-мозговой рефлекс любого С++-программиста. Да и использовать монструозный iostream в условиях нехватки памяти, не самое умное решение. Уж лучше write или fputs, если не POSIX-ы нужны.

Не прощу %)) нет, не только в универе... но спинно-мозгового рефлекса у меня не вырабаталось, плюсы это не основное в моей работе... а пример был написан на скорую руку, и не как какой-то стандарт, а как указатель в какую сторону надо смотреть.

Cy6erBr4in ★★★
()
Ответ на: комментарий от Cy6erBr4in

> и что? все без исключения придерживаются стандартов? не смешите... (не говорю про конкретно этот случай с delete, а в общем...)

Большая тройка - MSVC, gcc, comeau таки придерживаются, и весьма неплохо. Исключения - либо очень труднореализуемы (export templates, да и тот уже поддерживается), либо в хитрозапутанных шаблонах. delete 0 - поддерживается везде.

Всякие маргинальные компиляторы на встраиваемых железках, symbian-ах и прочем в расчёт не берём, это просто не С++, и с ними совершенно другой разговор. В них и исключений может не быть, и стек не раскручиваться, и STL кастрированный, и прочие «прелести».

> Не прощу %)) нет, не только в универе... но спинно-мозгового рефлекса у меня не вырабаталось, плюсы это не основное в моей работе... а пример был написан на скорую руку, и не как какой-то стандарт, а как указатель в какую сторону надо смотреть.

Никто вроде и не спорит с тем, что new кидает исключение. Просто код if (p) delete p; встречается достаточно часто и без этого (простейший пример - lazy initialization), и это слегка раздражает. И читабельность портится ненужными деталями, и проверка двойная получается. Некоторые уникумы ещё и присваивают NULL члену-указателю в деструкторе.

anonymous
()
Ответ на: комментарий от anonymous

Большая часть проблем, которые ты описал, возникает из-за нашего всеми горячо любимого преподавания в ВУЗах... не побоюсь сказать, процентов 70% преподов (я в этом почти уверен) моего универа, не в курсе про то, что new (теперь уже) вызывает исключение, а не возвращает ноль... грустно это :(

Cy6erBr4in ★★★
()
Ответ на: комментарий от grob

>бегом читать стандарт зи-блюз-блюз

ну его нафиг

но указатель то уж стоит нулём инициализировать?

anonymous
()
Ответ на: комментарий от anonymous

> но указатель то уж стоит нулём инициализировать?

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

vgudkov
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.