Гарантируется ли, что memset обнулит биты заполнения в структуре? - PullRequest
10 голосов
/ 18 декабря 2011

Как правило, согласно стандарту C гарантируется, что memset () с 0 обнулит биты заполнения в структуре C?

А как насчет gcc?

Например, что-то вроде:

struct MyStruct
{
    unsigned char   member1;
    unsigned int    member2;
    char        member3;
    unsigned char   member4;
    float       member5;    
};

struct MyStruct ms;

memset(&ms, 0, sizeof( struct MyStruct));

Ответы [ 3 ]

15 голосов
/ 18 декабря 2011

Возможно, стоит отметить, что memset ничего не знает о вашей структуре (или массиве, или примитиве, или о каком-либо фрагменте памяти, независимо от того, на что вы случайно его высвободили), так что даже если он хотел оставить биты заполнения нетронутыми, он даже не узнает, где они находятся.

11 голосов
/ 18 декабря 2011

Да, memset записывает 32-битное значение в непрерывную область памяти заданной длины, начиная с заданного адреса. В вашем случае memset записывает регион с (32-битное значение) 0.

Так что если вы делаете memset длины sizeof (your_struct), у вас все будет в порядке:

memset(&ms, 0, sizeof(struct MyStruct));
8 голосов
/ 18 декабря 2011

Если это имеет значение, вы, вероятно, делаете что-то небезопасное и непереносимое.

Да, вызов memset установит для любых битов заполнения (или байтов) значение 0, но на языке нет гарантии, что установка объекта float в значение all-bits-zero установит его в 0.0. То же самое относится и к указателям: нулевые все-биты не обязательно являются нулевыми указателями. (В обоих случаях это справедливо для большинства реализаций.)

Исходный стандарт ISO C90 или C99 даже не гарантировал, что ноль со всеми битами является действительным представлением 0 для целочисленных типов; одно из Технических исправлений после C99 добавило такую ​​гарантию (только для целых типов).

Для переносимости, если вы хотите, чтобы что-то было равно нулю, установите это явно. Вы также можете воспользоваться инициализацией с нулевым значением для статических объектов и для пропущенных членов в инициализаторах.

Терминологическая мелочь: «биты заполнения» являются частью представления целочисленных типов (и обычно их нет). Заполнение между членами структуры - это заполнение байтов .

...