关于向量记忆行为的问题

bam*_*bam 5 c++ stl stdvector c++11

我最近对内存(de)分配感到困惑 std::vectors

让我们假设我得到了整数的正常向量: std::vector<int> intv;当我push_back有时int它会随着时间而增长.当我离开函数的范围(即)时,它会被释放,而不需要额外的调用.

大.让我们举另一个例子:

struct foo_t{
    std::string bar:
    unsigned int derp;
}
void hurr(){
    std::vector<foo_t> foov;
    foo_t foo;
    foo.bar = "Sup?";
    foo.derp = 1337;
    foov.push_back(foo);
}
Run Code Online (Sandbox Code Playgroud)

好的.当我调用hurr()vector创建时,会创建一个foo_t实例,实例将被填充并推送到向量.因此,当我离开函数时,向量将被释放,内容(此处为一个foo_t)也会被释放?

下一个例子:

struct foo_t{
    std::string bar:
    unsigned int derp;
}
std::vector<foo_t> hurr(){
    std::vector<foo_t> foov;
    foo_t foo;
    foo.bar = "Sup?";
    foo.derp = 1337;
    foov.push_back(foo);
    return foov;
}
Run Code Online (Sandbox Code Playgroud)

在我的理解中,向量及其内容存在于堆栈中,它最终被时间覆盖并且我返回的向量和其内容将是无用的.或者它实际上是否返回了带有其内容副本的向量副本(如果它不是POD,则需要内容数据类型的Copy-Constructor)?

显而易见的事情:

struct foo_t{
    std::string bar:
    unsigned int derp;
}
std::vector<foo_t*> hurr(){
    std::vector<foo_t*> foov;
    foo_t foo = new foo_t;
    foo->bar = "Sup?";
    foo->derp = 1337;
    foov.push_back(foo);
    return foov;
}
Run Code Online (Sandbox Code Playgroud)

现在我必须手动迭代向量,删除其内容然后我可以安全地让向量超出范围,对吗?

Dan*_*anh 3

这个例子:

struct foo_t{
    std::string bar;
    unsigned int derp;
};
void hurr(){
    std::vector<foo_t> foov;
    foo_t foo;
    foo.bar = "Sup?";
    foo.derp = 1337;
    foov.push_back(foo);
}
Run Code Online (Sandbox Code Playgroud)

完成后hurv()foov两人foo都被释放了。

std::vector<foo_t> hurr(){
    std::vector<foo_t> foov;
    foo_t foo;
    foo.bar = "Sup?";
    foo.derp = 1337;
    foov.push_back(foo);
    return foov;
}
Run Code Online (Sandbox Code Playgroud)

std::vector<foo_t>的结果是有效的,其中hurr()包含 1并且它是有效的。foo_t可以return foov; 调用的复制构造函数std::vector<foo_t>,并且它可以自由地不进行该复制,请参阅复制省略

无论如何,从 C++11 开始,你可以这样写:

struct foo_t{
    std::string bar;
    unsigned int derp;
    // we will copy the string anyway, pass-by-value
    foo_t(std::string bar_, unsigned int d_)
        : bar(std::move(bar_)), derp(d_) {}
};
std::vector<foo_t> hurr(){
    std::vector<foo_t> foov;
    // This is better, in place construction, no temporary
    foov.emplace_back("Sup?", 1337);
    // This require a temporary
    foov.push_back(foo_t{"Sup?", 1337});
    return foov;
}
Run Code Online (Sandbox Code Playgroud)

而且,对于最后一个例子,是的,您必须手动迭代向量,删除其内容,然后当您不再想使用hurr(), (不在hurr())的结果时,我可以安全地让向量超出范围