6

我必须实现一个看起来像这样的函数:

MyList * sum (MyList * l1, MyList * l2) {
    MyList * newlist = new MyList();
    //Adds two objects and place the result in a third new list
    return newlist;
}

该函数采用两个列表并将每个对象的总和放入一个新列表中。该类MyList具有指向next变量的节点,并且列表中的对象是用户定义的。

这让我开始思考——我应该如何处理对象和列表本身的内存动态分配?因为我必须为新列表的每个对象创建内存。

有没有办法将对象总和的值放在新列表中而不必依赖动态分配?也许通过做这样的事情:

Object result(node1->content + node2->content);
Node->content = &result; // will this object be erased when the function ends?

而不是这个:

Node->content = new Object(node1->content + node2->content);

我应该如何处理函数内部创建的新列表的生命周期与函数结束后将保存内存的变量相关?返回新列表时我可以这样做吗?

MyList & sum (MyList * l1, MyList * l2) {
    //Create variable without allocating memory and return it's reference 
}

简而言之,我的主要疑问是如何处理在函数内部创建并由其他对象持有的对象的生命周期。

4

2 回答 2

2
Node->content = &result; // will this object be erased when the function ends?

是的,因为它是一个局部变量。一旦它的功能终止,它result的生命周期也会终止。


MyList & sum (MyList * l1, MyList * l2) {
    //Create variable without allocating memory and return it's reference 
}

由于与上述类似的原因,这也会失败。


我建议你使用std::shared_ptror std::unique_ptr。如果您愿意,请阅读unique_ptr 和 shared_ptr 之间的差异

于 2017-08-30T16:37:58.337 回答
0
Object result(node1->content + node2->content);
Node->content = &result; // will this object be erased when the function ends?

是的,如果result在函数体中按照上面所示的语法创建,它会在函数结束时被销毁。

这就是您应该使用new动态分配的原因:通过这种方式,您的对象是在堆上(而不是本地函数堆栈)创建的,并且它们“存活”到创建它们的函数的末尾。您可以将返回的指针传回给调用者。当然,调用者必须正确delete返回指针,否则最终会导致内存(或其他资源)泄漏。

在现代 C++ 中,您应该使用已经定义的智能指针类,例如std::shared_ptror std::unique_ptr,并且您的代码几乎不应该使用显式 new的and delete(除非您正在开发一些自定义的高度优化的数据结构,并且您需要对内存分配 - 即使在这种情况下,显式代码调用newdelete应该安全地包装在 RAII 类边界内)。

但是,在我看来,您的代码更像是一个编程练习,并且这个练习的目的可能是学习使用显式newdelete. 事实上,在生产质量代码中,您可以使用已经可用的标准链表类模板,而不是滚动您自己的列表类,例如std::list.

于 2017-08-30T18:28:29.043 回答