Home > Blockchain >  C Crash on x64
C Crash on x64

Time:03-12

I have to do a little c reflection in my way, by creating a pointer for each property of my class(I have create a tool to help me generate corresponding c code), but surprise, Building on x86 mode worked fine, but on x64 mode it's crashed, I have no idea why! here is my code.

Product.h File

    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 File

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 file

 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 
        } 
    }

CodePudding user response:

Your ProductSchema class, and your main(), are leaking the objects they new.

You don't need to create an object at runtime to calculate offsets to its members, you can use offsetof() at compile-time instead.

Don't use int or unsigned long to perform calculations on pointers. They are not guaranteed to be large enough. Use (u)intptr_t instead.

Your singleton is not initializing its instance_ pointer before using it. It does not need to use dynamic memory at all.

Try this instead:

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

  • Related