c struct 通过偏移量抓取数据
假设我有这个结构:
typedef struct nKey {
int num;
widget* widget;
} NUMBER_KEY;
和一个函数:
void dialKey(widget* widget) {
// Need to print 'num' of the struct that this widget resides in
}
我该如何完成这个任务? 我尝试过类似的操作:
printf("%d", * (int *) widget - sizeof(int)); // Failure.org
编辑:可以安全地假设正在传递的小部件实际上是 NUMBER_KEY 结构的成员
编辑:寻找问题的解决方案而不是其他方法。
Lets say I have this struct:
typedef struct nKey {
int num;
widget* widget;
} NUMBER_KEY;
and a function:
void dialKey(widget* widget) {
// Need to print 'num' of the struct that this widget resides in
}
How do I go about accomplishing this? I tried something like:
printf("%d", * (int *) widget - sizeof(int)); // Failure.org
edit: it is safe to assume that the widget being passed is in fact a member of a NUMBER_KEY struct
edit: looking for a solution to the problem not another method.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
正如迈克尔在他的回答中解释的那样,你不能在给定的约束下做到这一点,因为没有办法“走回”指针图。 为了让事情变得更明显,让我画一个所涉及的对象图(用 C 语言术语,而不是 OOP 意义上的):
注意箭头。 它们是单向的——您可以从指针“行走”到指向的值,但不能“行走”回来。 因此,您可以遵循函数的
widget
参数来获取widget
对象,但是一旦到达,就无法知道还有谁指向它 - 包括widget
的任何实例code>NUMBER_KEY 结构。 想一想:如果您有十几个指向同一个widget
的其他指针,其中一些来自不同的NUMBER_KEY
对象,该怎么办? 如果不保留widget
对象中所有指针的列表,它怎么可能跟踪呢? 如果您确实需要这个,那么您必须这样做 - 让widget
指向其所属的NUMBER_KEY
。As Michael explains in his answer, you cannot do it with given constraints because there's no way to "walk back" the pointer graph. To make things more obvious, let me draw a diagram of objects (in C terms, not in OOP sense) involved:
Notice the arrows. They are one-way - you can "walk" from a pointer to pointed value, but you cannot "walk" back. So you can deference
widget
argument of your function to get to thewidget
object, but once there, there's no way to tell who else points at it - including any instances ofNUMBER_KEY
structs. Think about it: what if you had a dozen other pointers to the samewidget
, some of them from differentNUMBER_KEY
objects? How could it possibly track that without keeping a list of all pointers withinwidget
object? If you actually need this, it's what you'll have to do - makewidget
point to its owningNUMBER_KEY
.如果只将 widgit* 而不是 widgit** 传递给 dialKey,则无法执行您想要的操作(widgit* 值与 NUMBER_KEY 结构没有关系)。 假设你的意思确实是这样的:
微软有一个漂亮的宏来做这种类型的事情(它有助于能够拥有在 C 中一般操作链接列表的例程):
你可以像这样使用它:
Given just a widgit* and not a widgit** being passed into dialKey, there's no way to do what you want (a widgit* value has no relationship to the NUMBER_KEY struct). Assuming that you really mean something like:
Microsoft has a nifty macro for doing this type of thing (it helps with being able to have routines that manipulate linked lists genericly in C):
You could use this like so:
结构体的内存布局由编译器定义,只有在结构体成员之间有 0 字节填充时,您的代码才能工作。 通常不建议这样做,因为 0 字节填充会使您的结构覆盖大多数处理器的标准读取大小。
针对您的问题的一些有用的宏:
示例:
The memory layout of a struct is defined by your compiler, your code would only work if you have 0 byte padding between struct members. Usually this is not recommended b/c 0 byte padding would have your struct overlay across the standard read sizes of most processors.
Some useful macros for your problem:
example:
最安全的解决方案是在 widget 中保留指向相关 nKey 结构的指针
所有其他方法都是不安全的
The safest solution is to keep pointer to related nKey structure in widget
All other methods are unsafe
C 标准定义了
offsetof()
宏(在stddef.h
标头中定义),这在您的情况下很方便。请注意,您必须传递结构字段的地址,而不是值!
C standard defines
offsetof()
macro (defined instddef.h
header), which is handy in your case.Note that you have to pass an address of struct field, not a value!