У меня есть метод с моим пользовательским объектом в качестве параметра:
void processObject(Myobject instance)
{
//some code using instance
}
Я вызываю метод выше из другого метода:
...
processObject(*new MyObject());
...
Может ли это вызвать утечку памяти? Должен ли я вызвать что-то вроде delete & instance в методе объекта процесса?
Большое спасибо за вашу помощь!
РЕДАКТИРОВАТЬ
теперь я знаю, что есть утечка памяти, что бы вы предложили как самый простой способ исправить это? Моя идея - изменить этот код:
void processObject(Myobject* instance)
{
//some code using instance
delete instance;
}
...
processObject(new MyObject());
...
Мне нужен простой и быстрый способ исправить это, насколько это возможно (такая же проблема в коде во многих местах).
Вы не можете удалить объект экземпляра, что processObject
процедура получает, потому что это копия объекта, созданного с new
. Представьте себе это так:
new
, это создает объект в куче и дает вам MyObject*
MyObject
. Здесь вы также теряете указатель, так как вы его нигде не хранитеprocessObject
, и по мере того как подпись этой функции заявляет, копия вашего объекта создается и передается функцииКогда вы потеряли указатель, вы больше не сможете его удалить.
Решением не будет выделение объекта new
и передача refrence методу процесса:
void processObject(MyObject& ref) {
// do something with the reference
}
void test() {
MyObject x;
processObject(x);
// do stuff with x
}
Или выделите его new
и выполните следующее:
void processObject(MyObject* ptr) {
// do something with the pointer
}
void test() {
MyObject* x = new MyObject();
processObject(x);
// do stuff with x
delete x;
}
delete
;)
Пытаться:
class MyObject
{
public:
MyObject() { std::cout << "Reporting construction of object (ptr: " << (int)this << ")\n"; }
MyObject(const MyObject & other) { std::cout << "Reporting copy-construction of object (ptr: " << (int)this << ")\n"; }
MyObject(MyObject && other) { std::cout << "Reporting move-construction of object (ptr: " << (int)this << ")\n"; }
virtual ~MyObject() { std::cout << "Reporting destruction of object (ptr: " << (int)this << ")\n"; }
};
void DoSomething(MyObject obj)
{
}
int main()
{
DoSomething(*new MyObject());
}
Результат:
Reporting construction of object (ptr: 140173320)
Reporting copy-construction of object (ptr: -1078250292)
Reporting destruction of object (ptr: -1078250292)
Как вы видите, первый экземпляр не был уничтожен - таким образом, просочился.
В его нынешнем виде происходит утечка памяти. Вы можете удалить объект внутри функции processObject
адрес, однако подпись
void processObject(Myobject instance)
не мешает кому-либо передавать локальный объект variable/stack.
Myobject instance;
processObject(instance);
Если это произойдет, вы не сможете delete
объект.
Избегайте использования необработанных указателей и избегайте запутывания пользователей вашей функции.
Да, вы должны удалить его после нового, но вы не сможете удалить этот вновь созданный объект.
Всякий раз, когда вы пишете *new x;
, вы разыскиваете указатель на фактическую ссылку (или объект).
В вашем случае Myobject передается по значению и, таким образом, копируется, оставляя указатель не в пространстве стека и тем самым вызывая утечку памяти.
Я предлагаю вам использовать следующую процедуру вызова с почти таким же эффектом: (без утечки памяти): processObject(MyObject());
Я думаю, что вы, возможно, получили новый синтаксис с Java, где мы вынуждены его использовать. В C++ вы можете просто вызвать конструктор неявно, как это, и создать новый объект на месте, который затем передается как аргумент функции.
В этом случае объект строится на стеке и, следовательно, имеет автоматическую продолжительность хранения (без утечки памяти).
new
в первую очередь? Почему бы просто неprocessObject(MyObject());
?delete
где-нибудь? Нет, потому что ты не можешь. Итак, у вас есть утечка памяти.