【问题标题】:C++ is this a stack or heap allocation?C++ 这是堆栈还是堆分配?
【发布时间】:2012-02-03 16:57:40
【问题描述】:

从代码开始:

#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++,上面的 sn-p 代码让我很困惑。在 func1 中 addr4 和 addr6 的分配是堆栈分配(对吗?)。当 func1 存在时,它们应该消失(-ish,内存将保存该值,直到其他东西使用它)。这原本让我觉得我走的 ip2int 地图会打印垃圾。但是我从来没有能够做到这一点。

由于我还是 C++ 新手,我不排除我遗漏了什么。副本是否发生在我不知道的地方?我认为这对和地图插入调用都只是在引用。这应该意味着他们可以在某个时候引用垃圾。

好了,废话不多说。上面的代码是否有效,还是我只是走运而没有其他东西可以使用存储 addr4 和 addr6 的内存?

提前感谢您的任何帮助

【问题讨论】:

  • 我不知道 boost,但是检查某些东西是否分配了堆栈或堆的一种简单方法是使用调试器并放置断点(例如在构造函数上)。你可能有一个堆栈分配的数据,但内部字段是堆分配的......
  • @BasileStarynkevitch 您无法判断通过检查构造函数创建的堆或堆栈是否在两种情况下都调用了相同的构造函数。
  • 我的意思是在构造函数中放置一个断点,在运行时,在gdb调试器下...。然后,如果到达构造函数,调试器将能够显示它的this隐式参数,您将知道该指针是在堆栈上还是在堆上。

标签: c++ boost memory-management


【解决方案1】:

是的,当您执行 ip2int.insert<..>(..) 时会生成一个副本。

【讨论】:

【解决方案2】:

此代码有效。当您将地址/整数对插入地图时,您实际上是在制作地址对象的副本。因此名为“addr4”的堆栈本地地址对象不再存在,但它的副本(由地图拥有)存在。函数返回后,您正在访问的就是该副本。

【讨论】:

    【解决方案3】:

    插入std::map 会生成对象的副本。原始对象addr4addr6 具有自动存储期限,并在func1 结束时被销毁,但它们的副本在ip2int(具有静态存储期限)中愉快地存在,因此保证在期间有效程序执行。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 2012-07-29
        • 1970-01-01
        • 2019-10-25
        • 1970-01-01
        • 2016-12-27
        • 1970-01-01
        • 1970-01-01
        • 2012-11-23
        相关资源
        最近更新 更多