结构的内存分配/结构的值

Memory allocation of a structure / value of a structure

你能帮我理解为什么我的 dataStruct 结构的值不是其中一个成员的值吗? (至于simpleDataStruct结构)

我用这一行打印值:

printf("dataStruct:..............0x%X\r\n", dataStruct);

结果是:

dataStruct:..............0x22FE20

我使用 GCC。

我的代码是:

int main(void)
{
    typedef struct Main_SimpleStructData_s
    {
        unsigned char a;
        unsigned char b;
    }
    Main_SimpleStructData_t;

    typedef struct Main_StructuredData_s
    {
        unsigned char  a;
        unsigned char* b;
    }
    Main_StructuredData_t;

    unsigned char localDataA = 0xBE;
    unsigned char localDataB = 0xEF;
    unsigned char localDataC = 0xCA;
    unsigned char localDataD = 0xFE;

    Main_SimpleStructData_t  simpleDataStruct;
    Main_StructuredData_t    dataStruct;

    simpleDataStruct.a = localDataA;
    simpleDataStruct.b = localDataB;

    dataStruct.a    = localDataC;
    dataStruct.b    = &localDataD;

    printf("\r\n");
    printf("simpleDataStruct:........0x%X\r\n", simpleDataStruct);
    printf("Addr simpleDataStruct:   0x%X\r\n", &simpleDataStruct);
    printf("Size simpleDataStruct:   %u\r\n",   (unsigned)sizeof(simpleDataStruct));
    printf("\r\n");
    printf("Addr localDataC:         0x%X\r\n", &localDataC);
    printf("Size localDataC:         %u\r\n",   (unsigned)sizeof(localDataC));
    printf("Addr localDataD:         0x%X\r\n", &localDataD);
    printf("Size localDataD:         %u\r\n",   (unsigned)sizeof(localDataD));
    printf("dataStruct:..............0x%X\r\n", dataStruct);
    printf("dataStruct.a:            0x%X\r\n", dataStruct.a);
    printf("dataStruct.b:            0x%X\r\n", dataStruct.b);
    printf("Addr dataStruct:         0x%X\r\n", &dataStruct);
    printf("Addr dataStruct.a:       0x%X\r\n", &(dataStruct.a));
    printf("Addr dataStruct.b:       0x%X\r\n", &(dataStruct.b));
    printf("Size dataStruct:         %u\r\n",   (unsigned)sizeof(dataStruct));

    return (0);
}

结果是:

simpleDataStruct:........0xEFBE
Addr simpleDataStruct:   0x22FE4A
Size simpleDataStruct:   2

Addr localDataC:         0x22FE4D
Size localDataC:         1
Addr localDataD:         0x22FE4C
Size localDataD:         1
dataStruct:..............0x22FE20
dataStruct.a:            0xCA
dataStruct.b:            0x22FE4C
Addr dataStruct:         0x22FE30
Addr dataStruct.a:       0x22FE30
Addr dataStruct.b:       0x22FE38
Size dataStruct:         16

提前谢谢。

%X 转换采用 unsigned int 参数。您错误地传递了 struct Main_StructuredData_s,它不是 unsigned int,这是未定义的行为,所以我不知道为什么您希望看到一些合理的结果。

编辑:至于为什么Main_SimpleStructData_t通过显示它的成员出现在"work",答案仍然是它是未定义的行为,它可能会不管怎样,包括 "correct" 的东西。这种特殊情况的根本原因几乎可以肯定是:

  1. printf 尝试读取一个 unsigned int 参数(因为它不知道你实际传递了什么,当你说你传递了一个 unsigned int
  2. Main_SimpleStructData_t 恰好作为参数传递,方式与 unsigned int 相同(在您的平台上),而 printf 最终读取其成员的价值观。
  3. 较大的 Main_StructuredData_t 恰好以不同的方式作为参数传递(例如,在堆栈上而不是在寄存器中)并且 printf 读取一些随机值而不是因为 struct 不在 unsigned int 参数所在的位置。

当您调用函数 printf 时,参数被压入堆栈。

printf 在打印出堆栈中的值时弹出堆栈。堆栈不包含有关数据类型的信息,这是格式说明符的工作。

格式说明符告诉 printf 关于堆栈上传递的数据类型,然后知道这些参数的大小,否则它无法知道。

printf 不能像那样处理用户定义的结构,如果您提供格式说明符 %x 只会尝试一些操作,但这是未定义的行为。您可以写出带有 & 前缀的结构地址和结构成员,但不能写出结构本身。

您可以使用自定义格式说明符编写自己的 printf 函数,在按值传递结构后在内部打印出成员,但现在您还没有这样做。搜索 stdarg.h 以获取更多信息

@EOF、@Ctx、@Anders 和@Arkku:非常感谢您的帮助。我知道问题出在笔记本电脑和我的椅子之间 ;) 我是愚蠢的,但现在我是一个男人 :)

综上所述,我不知道如何正确使用 printf 函数。 GCC 已经通过警告向我做广告,但我没有阅读那些...

如果我的简单 Main_SimpleStructData_t 结构变得更复杂,行为是相同的:未定义!

typedef struct Main_SimpleStructData_s
{
    unsigned char a;
    unsigned int  c;  // Add a little bit complication
    unsigned char b;
}
Main_SimpleStructData_t;

结果变为:

simpleDataStruct:......0x22FE20  // Undefined behaviour also !
Addr simpleDataStruct: 0x22FE40
Size simpleDataStruct: 12