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

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

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

Ваулес, я получил:

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

Ответы

Ответ 1

Просто перейдите на memset (arr, -1, sizeof(arr));

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

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

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

Исключения:

  • 0 является исключением, поскольку, если вы установите все байты в 0, значение будет равно нулю
  • -1 - еще одно исключение, поскольку, поскольку Патрик подсвечивал -1, это 0xff (= 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.

Ответ 2

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

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

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

Ответ 3

gcc обеспечивает яркую комбинацию инициализации массива

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

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

Ответ 4

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

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

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

Ответ 5

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

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

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

Ответ 6

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

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

Что касается вашей версии, третьи аргументы - это количество элементов массива, поэтому вы получили свой результат. На самом деле, правда, вы должны назначить третьим аргументам ЧИСЛО БАЙТОВ, которые вы хотите. Поэтому правильная версия должна быть такой:

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