У меня проблема с утечкой памяти в C++.
Я создаю объект (новый TYPE) и передаю его подфункции. Я знаю, что мне нужно удалить объект, чтобы избежать утечек памяти, но, когда я вызываю delete на объекте внутри подфункции, это приводит к сбою приложения:
void subfunction (TYPE* oldObject,....) {
//deep-copy object
TYPE* object = new TYPE(oldObject->p1,oldObject->p2,....)
subfunction (object,....)
delete oldObject
}
В чем проблема? Нужно ли мне удалять объект в той же самой функции, в которой он был создан?
Мне не разрешено удалять объект внутри функции, который был аргументом для этой функции?
EDIT: сообщение об ошибке " * Ошибка в"./a.out ': free(): недопустимый размер: 0x00007fff4fbe59c0 * '
В чем проблема?
Вы, вероятно, дважды удаляете один и тот же объект. Это легко сделать, когда вы бросаете указатели и надеетесь, что что-то удалит его в нужное время.
Нужно ли мне удалять объект в той же самой функции, в которой он был создан?
Вы можете удалить его в любом месте (пока вы это делаете ровно один раз). Вы не должны этого делать, потому что жонглирование указателей делает почти невозможным гарантировать, что вы делаете это ровно один раз.
Мне не разрешено удалять объект внутри функции, который был аргументом для этой функции?
Вам разрешено; но вы не должны, так как вызывающий будет оставлен с висящим указателем. Если он пытается сделать что-либо с ним после удаления объекта, тогда могут возникнуть всевозможные ошибки.
Избегайте new
если вам это действительно нужно; и использовать интеллектуальные указатели для управления всем, что вы создаете с new
. Тогда вы можете продолжить писать полезный код, вместо того, чтобы отлаживать шаткую кучу памяти.
Я - нож для ног; к сожалению, моя система разбилась, и я не хранил trashmailaddress для входа, поэтому могу ответить теперь только как новый пользователь
фонбранд действительно дал правильный намек. Первый объект был инициализирован значениями по умолчанию как
TYPE c; TYPE* cp =&c;
как удалить такой элемент? возможно, автоматически в конце его области, что вызвало вторую операцию удаления и, следовательно, мою проблему.
Несколько строк, которые вы показываете, не позволяют вообще диагностировать проблему. Как говорят другие ответы и комментарии, это, вероятно, связано с удалением объекта дважды или, возможно, с удалением объекта, который не был задан new
. Или может быть, что какой-то другой код попирает ваш указатель или отклоняется за пределы выделенного объекта, и то, что, наконец, видит delete
, повреждено.
В C++ есть много вещей, которые вы можете сделать, не все из них обязательно хорошие идеи. И управление памятью сложно. Вы можете оставить большую часть этого языка (используя контейнеры, интеллектуальные указатели и т.д.), Или вы можете найти один из надстроек для сборки мусора.
Если вы хотите сделать это вручную, тщательно определите следующие моменты:
Настройте общие правила по всем типам объектов, если это возможно (чтобы помнить о разных правилах, гарантирует, что вы в конечном итоге примените неправильные, и в результате получите фейерверк). Некоторые простые правила приведены выше (новый/удалить в той же области, например, убедитесь, что new
вызывается только в конструкторах, delete
только в деструкторах другой), но они могут быть слишком строгими (объекты в куче и указателях велики именно потому, что время жизни объектов не должно совпадать с кодом).
Рассмотрите возможность использования средств трассировки/отладки выделения памяти, например valgrind. Но не зависеть от них, найти беспорядок и очистить его гораздо больше работы, чем немного планирования заранее. И вы можете не заметить беспорядок в своих тестах, в то время как закон Мерфи гарантирует, что он потерпит крах или иным образом плохо себя ведет в самое худшее время.
Проблема с управлением памятью заключается в том, что, хотя она в основном довольно проста (new/new [] → delete/delete []), становится сложнее, когда программа становится более сложной.
Вот почему сначала советуем избегать управления памятью. Это можно сделать, объявив объекты вместо указателей и используя стандартные библиотеки.
Если необходимо, используйте RAII для управления памятью (очистка в деструкторе), в первую очередь умные указатели (std :: unique_ptr, std :: shared_ptr).
Когда вы выполняете управление памятью с помощью (new/delete), выделяете и освобождаете память в той же области, так что легче отслеживать хорошее использование.
Если это действительно необходимо, удаление может быть выполнено в других областях, например, в функциях, но управлять ими может очень сложно.
Таким образом, в коде в вашем вопросе нет ничего, что непосредственно указывает на сбой, поэтому оно должно быть в сочетании с кодом, который вы не показывали.
Проблема в том, что вы, вероятно, ссылаетесь на oldObject на свое первоначальное место сразу после вызова подфункции (первоначальный вызов).
Приветствия.