C++访问不属于对象本身的内存
我想这听起来很奇怪,但我正在为硬件设备创建一些低级代码。根据具体条件,我需要分配比实际结构需要更多的空间,在那里存储信息并将对象本身的地址传递给调用者。
当用户释放这样的对象时,我需要在实际释放该对象之前读取这些信息。
目前,我正在使用简单的指针操作来获取地址(类或额外空间的地址)。然而,我认为如果我在内部(!)类型的成员函数中进行指针算术,会更容易理解。处理地址的分配器是唯一知道这一内部类型的分配器。换句话说,返回给用户的类型是不同的。
下面的例子说明了我的意思:
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;
}
这样做有争议吗?
It sounds weird, I guess, but I'm creating some low-level code for a hardware device. Dependend on specific conditions I need to allocate more space than the actual struct needs, store informations there and pass the address of the object itself to the caller.
When the user is deallocating such an object, I need to read these informations before I actually deallocate the object.
At the moment, I'm using simple pointer operations to get the addresses (either of the class or the extra space). However, I tought it would be more understandable if I do the pointer arithmetics in member functions of an internal (!) type. The allocator, which is dealing with the addresses, is the only one who know's about this internal type. In other words, the type which is returned to the user is a different one.
The following example show's what I mean:
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;
}
Is it arguable to do it in that way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这样做似乎不必要地复杂。如果我要实现这样的东西,我会采取一种更简单的方法:
这种实现略有不同,但(在我看来)更容易理解,并且不依赖于对存在或不存在的内容的深入了解。如果指针的所有实例都分配为 unsigned char 并按此删除,则用户不需要跟踪除块中的第一个地址之外的特定内存地址。
It seems needlessly complex to do it this way. If I were to implement something like this, I would take a simpler approach:
This implementation is subtly different, but much easier (in my opinion) to understand, and doesn't rely on intimate knowledge of what is or is not present. If all instances of the pointers are allocated as unsigned char and deleted as such, the user doesn't need to keep track of specific memory addresses aside from the first address in the block.
非常简单的想法:将额外的逻辑包装在工厂中,该工厂将为您创建对象并以智能方式删除它们。
The very straightforward idea: wrap your extra logic in a factory which will create objects for you and delete them smart way.
您还可以将结构创建为一个更大的对象,并使用工厂函数返回该结构的实例,但转换为一个更小的对象,该对象基本上充当该对象的句柄。例如:
现在您可以隐藏 foo 结构中可能需要的任何额外空间,对于工厂函数的用户来说,指针的实际值并不重要,因为它们主要与对象的不透明句柄。
You can also create the struct as a much larger object, and use a factory function to return an instance of the struct, but cast to a much smaller object that would basically act as the object's handle. For instance:
Now you can hide any extra space you may need in your
foo
struct, and to the user of your factory functions, the actual value of the pointer doesn't matter since they are mainly working with an opaque handle to the object.看来您的问题是流行的 结构的候选者破解。
“struct hack”在技术上是未定义的行为吗?
It seems your question is a candidate for the popular struct hack.
Is the "struct hack" technically undefined behavior?