列表和列表元素,存储在哪里?

dan*_*era 4 c++

鉴于这段代码:

#include <list>
(void) someFunction(void) {
    list <int> l;
    l.push_back(1);
}
Run Code Online (Sandbox Code Playgroud)
  • 列表的元素存储在哪里?堆?堆?
  • 如何凭经验检查值是堆栈还是堆?
  • 这个函数可以返回列表吗?编辑如果我声明函数为列表,函数返回列表没有问题吗?

示例(返回列表):

#include <list>
list<int> someFunction(void) {
    list <int> l;
    l.push_back(1);
}

...
l2 = someFunction();
l2.push_back(2);
Run Code Online (Sandbox Code Playgroud)

pro*_*ian 6

列表的元素存储在哪里?堆?堆?

列表元素存储在堆上.你可以在push_back方法调用的调试器后面看到这个.最容易看到的是存储对象而不是POD类型,并记录构造函数.你需要复制构造函数,因为它们被复制了.分配发生在模板参数分配器中,您可以指定它,也可以不指定它,它将使用默认的堆分配.

如何凭经验检查值是堆栈还是堆?

您可以使用堆栈中的push_back元素来检查:

std::list<int> my_list;
int a = 10;
my_list.push_back(a);
a = 11;
assert(*my_list.begin() == 10);
Run Code Online (Sandbox Code Playgroud)

这个函数可以返回列表吗?

在C++中,有两种传递数据的方法:引用或按值.如果你的功能看起来像这样,

list<int> func()
{
  list<int> res;
  res.push_back(10);
  return res;
}
Run Code Online (Sandbox Code Playgroud)

然后你按值传递列表,这意味着编译器将调用列表的复制构造函数,该构造函数也复制列表中的所有值.当函数返回时,在复制列表之后,将调用"res"列表的析构函数,释放其所有元素.但是,如果你这样做:

list<int>& func()
{
      list<int> res;
      res.push_back(10);
      return res;
}
Run Code Online (Sandbox Code Playgroud)

当您返回对"res"列表的引用时,您的代码将失败,该列表将在其作用域的末尾被销毁,因此您的引用将无效.

第一种解决方案的问题可能是性能问题.你也可以这样做而不需要像这样调用复制构造函数:

void func(list<int>& res)
{
  res.push_back(10);
}

list<int> list_to_fill;
func(list_to_fill);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,没有复制,它应该更快,因为只有一个列表创建.