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 代替。
不要使用int
或unsigned 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;
}
}
我必须以我的方式做一点 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 代替。
不要使用int
或unsigned 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;
}
}