C++ 访问内存,它不是对象本身的一部分
C++ Access memory which isn't part of the object itself
我想这听起来很奇怪,但我正在为硬件设备创建一些低级代码。根据具体情况,我需要分配比实际结构所需更多的空间,在那里存储信息,并将对象本身的地址传递给调用者。
当用户正在释放这样一个对象时,我需要在实际释放该对象之前阅读这些信息。
目前,我正在使用简单的指针操作来获取地址(类或额外空间的地址(。然而,我认为,如果我在内部(!(类型的成员函数中进行指针运算,这将更容易理解。处理地址的分配器是唯一知道这种内部类型的分配器。换句话说,返回给用户的类型是不同的。
下面的例子展示了我的意思:
struct foo
{
int& get_x() { return reinterpret_cast<int*>(this)[-2]; }
int& get_y() { return reinterpret_cast<int*>(this)[-1]; }
// actual members of foo
enum { size = sizeof(int) * 2 };
};
int main()
{
char* p = new char[sizeof(foo) + foo::size];
foo* bar = reinterpret_cast<foo*>(p + foo::size);
bar->get_x() = 1;
bar->get_y() = 2;
std::cout << bar->get_x() << ", " << bar->get_y() << std::endl;
delete p;
return 0;
}
这样做有争议吗?
这样做似乎不必要地复杂。如果我要实现这样的东西,我会采取一种更简单的方法:
#pragma pack(push, 1)
struct A
{
int x, y;
};
struct B
{
int z;
};
#pragma pack(pop)
// allocate space for A and B:
unsigned char* data = new char[sizeof(A) + sizeof(B)];
A* a = reinterpret_cast<A*>(data);
B* b = reinterpret_cast<B*>(a + 1);
a->x = 0;
a->y = 1;
b->z = 2;
// When deallocating:
unsigned char* address = reinterpret_cast<unsigned char*>(a);
delete [] address;
这种实现方式略有不同,但(在我看来(更容易理解,而且不依赖于对存在或不存在的深入了解。如果指针的所有实例都被分配为无符号字符并被删除,那么用户就不需要跟踪块中第一个地址之外的特定内存地址。
非常简单的想法:将您的额外逻辑封装在一个工厂中,该工厂将为您创建对象并以智能的方式删除它们。
您也可以将结构创建为一个更大的对象,并使用工厂函数返回结构的实例,但转换为一个更小的对象,该对象基本上充当对象的句柄。例如:
struct foo_handle {};
struct foo
{
int a;
int b;
int c;
int d;
int& get_a() { return a; }
int& get_b() { return b; }
//...more member methods
//static factory functions to create and delete objects
static foo_handle* create_obj() { return new foo(); }
static void delete_obj(foo_handle* obj) { delete reinterpret_cast<foo*>(obj); }
};
void another_function(foo_handle* masked_obj)
{
foo* ptr = reinterpret_cast<foo*>(masked_obj);
//... do something with ptr
}
int main()
{
foo_handle* handle = foo::create_obj();
another_function(handle);
foo::delete_obj(handle);
return 0;
}
现在,您可以在foo
结构中隐藏任何可能需要的额外空间,对于工厂函数的用户来说,指针的实际值无关紧要,因为它们主要使用对象的不透明句柄。
您的问题似乎是流行的结构破解的候选问题。
是";structhack";技术上未定义的行为?
相关文章:
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 提升 ASIO 无法识别计时器对象
- C 指针和对象作为不同类的一部分
- 为什么静态数据成员在 C++ 中不是对象的一部分
- 如果成员对象是父类的一部分,则无法创建成员对象
- 将二进制文件的一部分读入预先存在的basic_string对象
- 对象或引用的一部分
- 对数组的一部分进行对象搜索
- 当右值对象作为函数调用的一部分访问其成员时被销毁
- 当键是对象的一部分时,最合适的关联STL容器
- C++ 访问内存,它不是对象本身的一部分