如何通过指向结构中的松弛字节来访问另一个变量的数据?

How to access data of another variable by pointing to a slack-byte in a structure?

#include <stdio.h>
#include <stdlib.h>

struct someStruct {
    int ivar;
    char cvar;
    float fvar;
};

main(argc,argv)
const char** argv;
{
    struct someStruct someObj;
    someObj.ivar = 1;
    someObj.fvar = 2.3;
    someObj.cvar = 'r';
    printf("%u\n",&someObj.fvar);
    printf("%u\n",(&someObj.cvar + 4));
    printf("%f\n",*((&someObj.cvar) + 4));
    printf("%f\n",someObj.fvar);
}

这是我编写的程序,它试图通过将 char 的地址加 4 来访问 fvar 的地址。 我知道松弛字节的概念。我试图访问那段记忆,瞧!它正确地打印了地址。

printf("%u\n",&someObj.fvar);
printf("%u\n",(&someObj.cvar + 4));

两者打印相同的地址。

然后我尝试通过以下方式访问fvar:

printf("%f\n",*((&someObj.cvar) + 4));
printf("%f\n",someObj.fvar);

0.000000
2.300000

是我的结果。

然后我意识到 char* 和 float* 的解释不同。

因此,我尝试了从 char* 到 float* 再到 float 以及从 char 到 float* 再到 float 的各种类型转换,并且在所有可能的点上都尝试过,例如 typecasting the returned address to float,使用 4.0 而不是 4 (我意识到这不应该工作......但它没有),等等

不知何故,它只是不打印 2.300000 并继续打印 0.000000

我哪里漏掉了这个概念?

请注意,我有一个 64-bit MinGW 并添加了 slack-byte(我知道有些人没有),我已经验证过:

printf("%u",sizeof(someObj.ivar));
printf("%u",sizeof(someObj.fvar));
printf("%u",sizeof(someObj.cvar));
printf("%u",sizeof(someObj));

分别产生 44112 ....(sizeof(char) + 3)

P.S。我知道这是一个可怕的想法,但这是我通常学习概念的方式 XD

假设以下为真:

 &someObj.cvar + 4 == &someObj.fvar

您可以将指针值转换为适当的类型:

printf("%f\n", *(float*)((&someObj.cvar) + 4));

(&someObj.cvar)是一个指向char的指针,所以*(&someObj.cvar)是一个char%f printf 说明符需要 doublefloat,传递 char 是无效的。注意:float 当在可变参数函数中作为省略号参数中的参数之一传递时,隐式转换为 double,请参见 ex。 cppreference implicit conversions。您必须将 doublefloat 传递给 %f,而不是 char.

备注:

main(argc,argv)
const char** argv;
{

不要使用隐式 int 声明和旧的、已弃用的、过时的函数声明样式。使用普通样式:

int main(int argc, char **argv) {
  • printf("%u\n",&someObj.fvar); 是未定义的行为。 %u 需要 unsigned char,而不是 float *。您可以使用 %p 说明符打印 void* 指针:printf("%p\n", (void*)&someObj.fvar); 或将其转换为 unsinged intprintf("%u\n", (unsigned int)(uintptr_t)(void*)&someObj.fvar);

  • C 在 stddef.h 中声明了一个宏 offsetof 来访问 "slack-bytes" 的数量(我更喜欢名字 "padding bytes" )。您可以:printf("%f", *(float*)((char*)&someObj + offsetof(struct someStruct, fvar)));