【问题标题】:How to reliably calculate the memory address of an object [duplicate]如何可靠地计算对象的内存地址[重复]
【发布时间】:2023-03-08 08:03:01
【问题描述】:

我通过重载基类的 new 和 delete 运算符创建了自己的内存管理器。重载的运算符维护一个内存分配的链接列表,我还存储分配的文件和行号。它也适用于多重继承,因为删除运算符总是接收正确的内存地址(即我从“新”返回的地址)。我获取对象的内存地址(即第一个父对象的内存地址)的最佳方法是什么?

我想创建在运行时可以返回分配文件和行号的方法。对于多重继承,“this”指针可能不会指向正确的内存地址(有时偏移 8 个字节)。我理解为什么它是偏移的,但我正在寻找一种方法来可靠地计算新运算符最初返回的正确内存地址。

【问题讨论】:

    标签: c++


    【解决方案1】:

    如果类层次结构是多态的,则可以使用dynamic_cast<void*>(this)获取以*this为子对象的最派生对象的地址。

    另见this question


    如果你的类层次结构不是多态的,你就不能动态地知道给定的基对象是否是最衍生的,如果不是,你就无法知道它的最衍生对象是什么。但是,在这种情况下,您也无法销毁该对象,因为您无权访问最派生的析构函数,因此您通常不需要释放内存。但是,如果您无法确定其最派生的对象,您就无法查找该对象的分配跟踪。

    【讨论】:

    • 像往常一样,匿名投票者可能出于无知而投票。但是,我认为这个答案只是一个 in-practice 答案。 AFAIK 不能保证最派生对象的地址是operator new 返回的地址。
    • @Cheersandhth.-Alf:我认为这不会出错:当你说new Derived时,它会使用继承的operator new来准确获取sizeof(Derived)内存,它会在返回的地址构造对象。
    • 嗯,这就是我绝对不确定您是否正确的地方。但我认为它在实践中有效。
    【解决方案2】:

    你做不到。每个 C++ 编译器都可以对您从operator new 返回的存储执行任何操作。它可以选择任何类型的布局,然后new 操作的结果是某个指向从操作员返回的内存中某处的指针。最派生对象的地址和算子返回的值不一样。

    由于您没有指定您正在使用某个特定编译器的某些特定版本,因此没有人可以根据对实现相关细节的了解来给您答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-12
      • 1970-01-01
      • 1970-01-01
      • 2018-09-08
      • 2013-12-22
      • 1970-01-01
      • 2019-08-16
      • 2017-12-12
      相关资源
      最近更新 更多