Распределение памяти структуры / значения структуры - PullRequest
0 голосов
/ 28 декабря 2018

Можете ли вы помочь мне понять, почему ценность моей структуры 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 голосов
/ 28 декабря 2018

Когда вы вызываете функцию printf, аргументы помещаются в стек.

printf выдает стек при выводе значений из стека.стек не содержит информации о типе данных, то есть задании для спецификатора формата.

Спецификатор формата сообщает printf о типах данных, передаваемых в стеке, а затем знает размеры этих аргументов, в противном случае он не имеетспособ узнать.

printf не может обработать пользовательскую структуру, подобную этой, если вы зададите спецификатор формата% x, то просто попробует что-то, но это неопределенное поведение.Вы можете записать адрес структуры с префиксом его с & и / или членами структуры, но не с самой структурой.

Вы можете написать свою собственную функцию printf с пользовательским спецификатором формата, который внутренне печатаетчлены после передачи структуры по значению, но как это сейчас у вас нет.поиск stdarg.h для получения дополнительной информации

0 голосов
/ 28 декабря 2018

@ EOF, @Ctx, @Anders и @Arkku: Большое спасибо за вашу помощь.Я понимаю, что проблема между ноутбуком и моим стулом;) Я был глуп, но теперь я мужчина:)

Подводя итог, я не знаю, правильно ли использовать функцию printf.GCC был объявлен мне с предупреждениями, но я их не читал ...

Если моя простая структура Main_SimpleStructData_t усложняется, поведение остается таким же: Undefined!

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
0 голосов
/ 28 декабря 2018

Преобразование %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 заканчивается чтением в его членах'values.
  3. Чем больше Main_StructuredData_t, тем не менее, в качестве аргумента передается другим способом (например, в стеке, а не в регистре), а printf считывает некоторое случайное значение вместо этого, потому что struct не там, где был бы аргумент unsigned int.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...