You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不创建实例即可获取继承结构体中基类的偏移量

非虚继承多基类偏移量计算方法

手动计算规则(适用于逆向场景,和编译器默认内存布局一致)

非虚继承场景下,基类在派生类中的偏移完全由继承顺序、基类自身大小和对齐规则决定,遵循以下规律:

  • 派生类按照继承声明的先后顺序,依次排列每个基类的完整子对象
  • 每个基类子对象的内存布局、大小、对齐要求和单独实例化该类的结果完全一致
  • 包含虚函数的类开头会隐含一个对应架构位数的虚表指针(32位下4字节,64位下8字节)
  • 所有成员按自身对齐要求排列,类总大小对齐到类内最大对齐成员的整数倍

以你给出的代码为例,64位架构默认对齐下的计算过程:

  1. 计算struct A的大小:
    开头隐含8字节虚表指针 → 8字节int64 member → 4字节int32 member2 → 末尾填充4字节对齐到8的整数倍,总大小为24字节(0x18)
  2. struct C的继承顺序是先A后B,因此A子对象放在C的起始地址,B子对象紧随A之后,所以B在C中的偏移就是A的大小24(0x18),和IDA中高亮的结果一致。

代码实现方法

你之前的空指针转换写法属于C++标准未定义行为,部分编译器开优化后会得到错误结果甚至编译报错,推荐使用以下标准兼容的编译期计算方法:

#include <cstddef>
#include <type_traits>

template <typename Derived, typename Base>
constexpr ptrdiff_t get_base_offset() noexcept {
    // 仅支持非虚继承场景,虚继承偏移不固定不可用该方法
    static_assert(!std::is_virtual_base_of_v<Base, Derived>, "不支持虚继承场景");
    // 分配一块对齐的内存模拟派生类实例,避免空指针未定义行为
    alignas(Derived) unsigned char buf[sizeof(Derived)]{};
    const Derived* derived_ptr = reinterpret_cast<const Derived*>(buf);
    const Base* base_ptr = derived_ptr;
    return reinterpret_cast<const char*>(base_ptr) - reinterpret_cast<const char*>(derived_ptr);
}

// 调用示例
// ptrdiff_t b_in_c_offset = get_base_offset<C, B>();

该方法可以在编译期得到正确的偏移值,兼容所有符合C++11及以上标准的编译器。

内容的提问来源于stack exchange,提问作者Lucas Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 13:36:04