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

时间:2018-12-28 10:57:45

标签: c gcc 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

预先,谢谢。

3 个答案:

答案 0 :(得分:1)

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

edit :关于Main_SimpleStructData_t为何通过显示其成员而看起来“起作用”的原因,答案仍然是它是未定义的行为,它可能会做任何事情,包括“正确”的行为事情。在这种情况下的根本原因几乎可以肯定是:

  1. printf尝试读取一个unsigned int参数(因为当您说您通过了unsigned int时,它不知道您实际通过了什么)
  2. 小的Main_SimpleStructData_t恰好像参数unsigned int在您的平台上一样作为参数传递,而printf最终在其成员的内容中读取值。
  3. 较大的Main_StructuredData_t恰好以不同的方式作为参数传递(例如,在堆栈上而不是在寄存器中),而printf则读取一些随机值,因为{{1 }}不在struct参数所处的位置。

答案 1 :(得分:1)

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

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

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

printf无法像这样处理用户定义的结构,如果您给格式说明符%x将尝试某些操作,但这是未定义的行为。您可以用&和/或结构成员写出结构前缀的地址,但不能写出结构本身。

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

答案 2 :(得分:0)

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

总而言之,我不知道正确使用printf函数。海湾合作委员会已经给我打了警告,但我没有读那些警告。

如果我的简单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