LINUX.ORG.RU

Выравнивание данных в структурах

 


0

1

День добрый.

Мучаюсь уже который час. Есть структура:

struct __data {
    int msg;
    char key[32];
    time_t timestamp;
    unsigned long data_crc32;
    void *data_bin;
};

Далее, есть функция, которая с ней работает:

...
struct __data data;

memset(&data, 0, sizeof(struct __data));
    
data.msg            = msg;
memcpy(data.key, secret_key, 32);
data.data_bin       = rsp;
data.timestamp      = CURRENT_TIMESTAMP;
data.data_crc32     = crc32(0, rsp, rsp_size);
...
Далее, собственно, WTF:

...
strlen(secret_key) = 32
strlen(data.key)     = 49

Флаги сборки: -g -Wall -Wstrict-prototypes

Вопрос: КАК, ПОЧЕМУ, откуда там 49 ? О_о

Если добавить -O2, то там уже не 49, а 51!

Компилятор:

$clang --version
clang version 3.1 (branches/release_31)
Target: i386-pc-linux-gnu
Thread model: posix

UPD

C GCC 4.7.2, и с -O2: 65, и без -O2, 51.

★★★★★

strlen работает с null-terminated строками, а в структуре у тебя никакого нулевого байта уже нет. Либо делай key[33] и копируй туда через strcpy, а не memcpy, либо не используй строковые функции для data.key.

#pragma pack тут вообще не при чём.

slovazap ★★★★★ ()
Ответ на: комментарий от soomrack

#pragma pop(push)

warning: unknown pragma ignored [-Wunknown-pragmas]

#pragma pop(push)

^

1 warning generated.

Наверное, так:

#pragma pack(pop)

Но не суть, длинна теперь 57.

joy4eg ★★★★★ ()

А где у тебя secret_key, и, как уже сказали, почему ты не пользуешься strcpy?

UVV ★★★★★ ()
Ответ на: комментарий от slovazap

#pragma pack тут вообще не при чём.

Без нее выравнивание останется на совести компилятора, т.е. как ТС и заметил, будет разная в зависимости от опций оптимизации.

soomrack ★★★ ()
Ответ на: комментарий от UVV

secret_key это extern char*, добавил место для '\0', и все заработало :)

joy4eg ★★★★★ ()
Ответ на: комментарий от joy4eg

Добавлю, что лучше использовать strlcpy чтобы не выдти за пределы буфера и гарантировать что строка завершена нулём.

slovazap ★★★★★ ()
Ответ на: комментарий от soomrack

Без нее выравнивание останется на совести компилятора, т.е. как ТС и заметил, будет разная в зависимости от опций оптимизации.

А какая в данном примере разница, как происходит выравнивание?

anonymous ()
Ответ на: комментарий от anonymous

А какая в данном примере разница, как происходит выравнивание?

Это был ответ на замечание ТС «Если добавить -O2, то там уже не 49, а 51!» Т.е. про то, почему «разное», но не почему «не правильное».

Полный ответ на пост ТС это \0 + pack.

soomrack ★★★ ()
Ответ на: комментарий от soomrack

Да что за чушь-то? pack к данной теме вообще никаким боком не относится.

slovazap ★★★★★ ()
Ответ на: комментарий от slovazap

Вопрос: КАК, ПОЧЕМУ, откуда там 49 ? О_о

\0

Если добавить -O2, то там уже не 49, а 51!

pack

soomrack ★★★ ()
Ответ на: комментарий от soomrack

facepalm.jpg Оптимизация не влияет на упаковку структур. Она могла повлиять на то, что попало в мусор в неиспользуемом месте структуры или после неё, поэтому ноль и прыгал.

slovazap ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.