Почему "memset (arr, -1, sizeof (arr) / sizeof (int))" не очищает целочисленный массив до -1? - PullRequest
43 голосов
/ 26 августа 2011

Разве нельзя использовать memset для массива целых чисел? Я попробовал следующий вызов memset и не получил правильные целочисленные значения в массиве int.

int arr[5];
memset (arr, -1, sizeof(arr)/sizeof(int));

Vaules, которые я получил:

arr[0] = -1
arr[1] = 255
arr[2] = 0
arr[3] = 0
arr[4] = 0

Ответы [ 6 ]

73 голосов
/ 26 августа 2011

Просто измените на memset (arr, -1, sizeof(arr));

Обратите внимание, что для других значений, кроме 0 и -1, это не будет работать , поскольку memset устанавливает значения байтов для блокапамяти, которая начинается с переменной, обозначенной *ptr для следующих num байтов.

void * memset ( void * ptr, int value, size_t num );

И поскольку int представлен более чем в одном байте, вы не получите желаемого значения для целых чисел в вашем массиве.

Исключения:

  • 0 является исключением, поскольку, если вы установите все байты равными 0, значение будет равно нулю
  • -1 - еще одно исключение, так как Патрик выделил -10xff (= 255) в int8_t и 0xffffffff в int32_t

Причина, по которой вы получили:

arr[0] = -1
arr[1] = 255
arr[2] = 0
arr[3] = 0
arr[4] = 0

Причина в том, что в вашем случае длина int составляет 4 байта(32-битное представление), длина вашего массива в байтах составляет 20 (= 5 * 4), и вы устанавливаете только 5 байтов в -1 (= 255) вместо 20.

33 голосов
/ 26 августа 2011

Не используйте memset для инициализации чего-либо, кроме однобайтовых типов данных.

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

Правильный способ инициализации массива от int до -1, это циклически проходить по массиву и явно устанавливать каждое значение.

10 голосов
/ 14 апреля 2014

GCC обеспечивает хороший ярлык инициализации массива

int arr[32] = {[0 ... 10] = 3, [11 ... 31] = 4}

обратите внимание на пространство до и после ...

5 голосов
/ 26 августа 2011

Почему деление?

memset(arr, -1, sizeof(arr));

Ваша версия, sizeof(arr)/sizeof(int), дает вам количество элементов в массиве.

4 голосов
/ 26 августа 2011

Вы можете сэкономить время при наборе, непосредственно инициализируя массив:

int arr[5] = {-1, -1, -1, -1, -1}; 

Эта строка короче чем memset, и она также работает.

1 голос
/ 24 апреля 2015
void * memset ( void * ptr, int value, size_t num );

Эта функция хорошо работает в большинстве систем, когда применяется для установки массива char.Он устанавливает первое число байтов блока памяти, указанного указателем ptr, в указанное значение (интерпретируемое как беззнаковый символ). memset-C ++ Ссылка Он работает один байт каждый раз. Так что он работает нормально, если назначитьвторые аргументы со значением int не более 0xff.

Что касается вашей версии, то третьи аргументы - это количество элементов массива, так что вы получили свой вывод.На самом деле правда в том, что вы должны назначить третьим аргументам желаемое количество байтов.Поэтому правильная версия должна быть такой:

memset (arr, -1, sizeof(arr));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...