x64 上的 C++ 崩溃

C++ Crash on x64

我必须以我的方式做一点 C++ 反射,通过为我的 class 的每个 属性 创建一个指针(我已经创建了一个工具来帮助我生成相应的 C++ 代码),但令人惊讶的是,在 x86 模式下构建工作正常,但在 x64 模式下它崩溃了,我不知道为什么!这是我的代码。

Product.h 文件

    class Product
    {
    public:
        int ID;
        std::string  Designation;
    };
  class Property
    {
    public:
        std::string Name;
        int Shift;
    };
    class ProductSchema
    {
    private: 
        ProductSchema();
    public: 
        static ProductSchema* Default();
        ProductSchema(const ProductSchema& other) = delete;
        Property ID;
        Property Designation;
        Property Prix;
    };

Product.cpp 文件

ProductSchema::ProductSchema()
{  
    Product* p = new Product(); 
    ID.Name = "ID";
    ID.Shift = (int)(int*)&p->ID - (int)p;    

    Designation.Name = "Designation";
    Designation.Shift = (int)(int*)&p->Designation - (int)p;
}
ProductSchema* ProductSchema::Default()
{
    static ProductSchema* instance_;
    if (instance_ == nullptr)
        instance_ = new ProductSchema;
    return instance_;
}

main.h 文件

 int main()
    {     
        for (int i = 0; i < 10000; i++)
        {
            Product* p = new Product();
            int* pID = (int*)((unsigned long int)p + ProductSchema::Default()->ID.Shift);
            *pID = i; // <--- error here 
        } 
    }

您的 ProductSchema class 和您的 main() 正在泄漏他们 new 的对象。

您不需要在运行时创建对象来计算其成员的偏移量,您可以使用 offsetof() at compile-time 代替。

不要使用intunsigned long 对指针进行计算。不能保证它们足够大。请改用 (u)intptr_t

您的单例在使用前未初始化其 instance_ 指针。它根本不需要使用动态内存。

试试这个:

class Product
{
public:
    int ID;
    std::string Designation;
};
 
struct Property
{
    std::string Name;
    int Shift;
};

class ProductSchema
{
private: 
    ProductSchema();
public: 
    static ProductSchema& Default();
    ProductSchema(const ProductSchema& other) = delete;
    Property ID;
    Property Designation;
    Property Prix;
};
ProductSchema::ProductSchema()
{  
    ID.Name = "ID";
    ID.Shift = offsetof(Product, ID);    

    Designation.Name = "Designation";
    Designation.Shift = offsetof(Product, Designation);
}

ProductSchema& ProductSchema::Default()
{
    static ProductSchema instance_;
    return instance_;
}
int main()
{     
    for (int i = 0; i < 10000; i++)
    {
        Product p;
        int* pID = reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(&p) + ProductSchema::Default().ID.Shift);
        *pID = i;
    } 
}

Online Demo