Способ восстановить утечку памяти из динамического выделения в C ++? - PullRequest
0 голосов
/ 25 марта 2019

Если я напишу:

b = new int;
b = new int; 
delete b;

Я знаю, что только вторая b удаляется из памяти. Поскольку ничто не указывает на первый b (из-за удаления 2-го b), у меня есть утечка памяти.

В таких случаях я знаю, что существует способ устранить утечку памяти в C # и Java. Есть ли способ восстановить эту утечку памяти в C ++?

Ответы [ 2 ]

1 голос
/ 25 марта 2019

Вариант 1 .

Самый простой способ - полностью избежать new и delete.

Вместо:

b = new int;
b = new int; 
delete b;

Запись:

std::unique_ptr<int> b;
...
b = std::make_unique<int>();
b = std::make_unique<int>(); 

Когда b перезаписывается или выходит из области видимости, это освобождает память. Нет delete требуется или даже разрешено. Обратите внимание, что это похоже на сборщик мусора Java, но в большинстве случаев достаточно хорошо.

Вариант 2.

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

ПРИМЕЧАНИЕ : Использование unique_ptr не так безопасно, как в языках с сборкой мусора, таких как C #, Java и Python. Он терпит неудачу, когда нет четкой модели владения и когда существует круговое владение. Если элемент a имеет от unique_ptr до b, а b имеет от unique_ptr до a, то они никогда не будут освобождены. Они никогда не будут освобождены, поскольку unique_ptr освобождает объект в деструкторе, но никто не будет вызывать деструктор ни a, ни b. Если никто не вызывает деструктор, то unique_ptr никогда не удалит объект и никогда не вызовет деструктор другого объекта.

ПРИМЕЧАНИЕ 2 : Иногда вместо unique_ptr следует использовать std::shared_ptr, но это не решает проблему циклических ссылок. Это только решает проблему нескольких владельцев одного объекта.

ПРИМЕЧАНИЕ 3 : эти интеллектуальные указатели не снижают вероятность переполнения стека из-за глубокой рекурсии в деструкторах. Это может произойти при рекурсивном уничтожении длинных связанных списков или в несбалансированных бинарных деревьях. Использование unique_ptr для этого случая просто скрывает тот факт, что рекурсия имеет место.

0 голосов
/ 25 марта 2019

Я знаю, что есть способ восстановить эту утечку памяти в C # и Java

Java и C # оба являются языками для сбора мусора, поэтому они обычно не имеют утечек памяти (это практически невозможно), но когда они происходят, вы можете выдать исключение,

Есть ли способ устранить эту утечку памяти в C ++?

в c ++ утечки памяти более распространены, потому что вы вручную выделяете память каждый раз, когда создаете указатель, поэтому вы всегда будете выдавать исключение, чтобы указать, есть ли утечка памяти, где произойти, где она и как с ней бороться это ... так что ответ на ваш вопрос ... нет, вы не можете восстановить после утечки памяти в c ++, это язык "Down To The Metal", поэтому он настолько уязвим, если не написано правильно, но вы всегда можете бросить Исключение составляют случаи, когда происходит утечка памяти, вы можете указать ее и посмотреть, как ее исправить.

...