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

Невозможно использовать 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 

Просто измените на 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.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 memset (arr, -1, sizeof(arr)); 
  • Почему мы не можем использовать двойной указатель для представления двухмерных массивов?
  • Правильный способ передачи 2-мерного массива в функцию
  • Путаница вычитания указателя
  • Левое смещение с отрицательным сдвигом
  • локальная переменная, инициализированная нулем в C
  • Плакат с 8 этапами перевода на языке C
  • Функция scanf getchar пропускается
  • Почему ++ i ++ дает «L-значение требуемой ошибки» в C?
  • Использование \ b и \ r в C
  • Странное предупреждение компилятора C: предупреждение: «struct» объявлен в списке параметров
  • Gcc автоматически инициализирует статические переменные до нуля?
  • Давайте будем гением компьютера.