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