C ++是堆栈还是堆分配?

时间:2012-02-03 16:57:40

标签: c++ boost memory-management

从代码开始:

#include <iostream>
#include <string>
#include <map>

#include <boost/asio.hpp>

typedef std::map<boost::asio::ip::address, int> Ip2Int;
Ip2Int ip2int;

void
func1()
{
    boost::asio::ip::address addr4 = boost::asio::ip::address::from_string("192.168.2.1");
    boost::asio::ip::address addr6 = boost::asio::ip::address::from_string("de::ad");

    ip2int.insert(std::pair<boost::asio::ip::address, int>(addr4, 1));
    ip2int.insert(std::pair<boost::asio::ip::address, int>(addr6, 2));
}

int
main()
{
    func1();

    Ip2Int::iterator iter = ip2int.begin();
    do {
        std::cout << iter->first << " -> " << iter->second << std::endl;
    } while (++iter != ip2int.end());

    return 0;
}

我正在学习C ++,上面的代码片段让我感到困惑。在func1中,addr4和addr6的分配是堆栈分配(对吗?)。当func1存在时,它们应该消失(-ish,内存将保留值,直到其他东西使用它)。这最初让我觉得我走ip2int地图可能会打印垃圾。但我从来没有能够实现这一点。

因为我还不熟悉C ++,所以我不排除我错过了什么。副本是否发生在我不知道的地方?我认为对和插图调用只是引用。这应该意味着他们可以在某些时候提到垃圾。

好的,足够漫无边际。以上代码是否有效,或者我只是幸运而没有其他任何东西可以使用存储addr4和addr6的内存?

提前感谢任何和所有帮助

4 个答案:

答案 0 :(得分:2)

此代码有效。将address / int对插入映射时,实际上是在制作地址对象的副本。因此,名为“addr4”的堆栈本地地址对象不再存在,但它的副本(由映射拥有)可以。这是函数返回后正在访问的副本。

答案 1 :(得分:2)

是的,当您执行ip2int.insert&lt; ..&gt;(..)时会复制一份。

答案 2 :(得分:1)

插入std::map会复制该对象。原始对象addr4addr6具有自动存储持续时间,并在func1结束时被销毁,但是他们的副本在ip2int(具有静态存储持续时间)中幸福地存在因此保证在程序执行期间有效。

答案 3 :(得分:0)

Stl要求使用其容器的对象的对象是一个可复制构造的对象。所以听到的是ip2int在全球范围内是自动的,并且在程序的生命周期中存在。在Func1中,您将创建两个自动变量并将它们复制到地图中。 Map的底层使用堆分配来包含值。当func1存在时,清除automatics中的内存并调用析构函数,但map仍然存在,并且创建的副本仍然存在。