是否未使用“分配对象”;新";在堆栈或堆上分配 我是C++新手,所以问题是基本的。< /P>
假设我定义了一个类Foo,并在以下代码中创建了一个向量向量:是否未使用“分配对象”;新";在堆栈或堆上分配 我是C++新手,所以问题是基本的。< /P>,c++,C++,假设我定义了一个类Foo,并在以下代码中创建了一个向量向量: namespace testme { class Foo { public: Foo(int x): x_(x) { }; static vector<vector<int>> ReturnVecOfInts(int num) { vector<vector<int>>
namespace testme {
class Foo {
public:
Foo(int x): x_(x) { };
static vector<vector<int>> ReturnVecOfInts(int num) {
vector<vector<int>> ret(num);
for (int i = 0; i < num; i++) {
vector<int> tmp;
ret.push_back(tmp);
}
return ret;
}
}
是在堆或堆栈上创建的向量的向量。引用在堆栈上,但我想知道它是否指向堆,因为我想从函数返回这个对象
这对我来说很重要,因为很明显,如果在堆栈上分配这些向量,向量向量将超出范围,在调用的函数之外不可用。您可能想得太多了 在您的情况下,这样的代码是安全的:
Foo f = Bar::GetFoo();
通常,当您从函数返回对象时,可能会发生各种优化(例如RVO、NRVO等),但底线是您的f
对象可以安全使用
即使在Foo内部有一个数据成员,比如std::vector
,它通常从堆中分配内存(您可以使用自定义分配器自定义此行为),这要归功于复制构造函数、移动构造函数、析构函数等。从函数返回它或复制Foo实例都是完全安全的
编辑我注意到,在我写下答案后,您更改了代码,返回了
向量
,而不是Foo
。同样,我所写的仍然适用。完全取决于该声明所在的位置。如果它在名称空间范围内,那么对象具有静态存储持续时间,它既不是堆栈也不是堆。顺便说一下,请不要发布幻想代码:发布实数代码。C++中没有定义堆栈或堆的东西。这取决于你使用的系统。那就是为什么C++没有堆栈和堆的概念,而是使用自动和动态存储。通常,如果你在函数中声明它在堆栈上。如果它在一个堆分配的对象内,那么它也在堆上。这很大程度上取决于语句出现的上下文。因此,你真正的问题是:用值返回本地对象是否安全?是吗?从Ryan Haining的评论中,我知道C++返回实际对象。返回向量将返回对堆栈上分配的向量的引用向量,或不会超出范围的向量类型的对象向量。向量由嵌套向量生成。内部向量是vector,它们使用默认分配器从堆中分配一个连续的int块。外部向量是“向量”的向量,因此在这种情况下,内存布局更复杂。但归根结底,由于std::vector的正确实现细节,从函数返回vector很好。@CaptainJacksparrow基本上,一个vector
包装并管理一个动态分配的数组;可以安全地假设数组将在堆(或等效物)上创建,而管理部分(包括数组的地址)在堆栈(或等效物)上;管理部分是唯一需要返回的部分,因为数组不会被释放。[请注意,这适用于具有堆栈和堆的系统。更深奥的系统可能会以不同的方式处理std::vector
。还请注意,在实践中,它的工作方式可能与此不同;这只是一个简单的描述。]想象一下这样的情景:你的客厅里有一台电视,你和你的朋友正在观看。你有遥控器。如果你想让你的朋友负责电视,你是把电视放在他的膝上,还是把遥控器给他?
Foo f = Bar::GetFoo();