Почему «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)); 
  • atoi - как определить разницу между нулем и ошибкой?
  • Отключение политики одного и того же происхождения в Safari
  • Использование функции exit ()
  • Как представить 0,1 в арифметике с плавающей точкой и десятичной запятой
  • Оценка короткого замыкания и побочные эффекты
  • Использование нулевого оператора в C
  • srand (time (NULL)) не меняет начальное значение достаточно быстро
  • Преобразование int в строку в C
  • Как установить условную точку останова в Xcode на основе свойства объекта?
  • Печать изображений c # .net
  • Почему разделение двух целых чисел не дает поплавка?
  • Interesting Posts

    Как сообщить aptitude или apt предложить конкретную версию lpr?

    Macbook Pro не будет загружаться после исчерпания батареи

    Отправка электронной почты на Android с использованием API JavaMail без использования стандартного / встроенного приложения

    Является ли механизм блокировки на оборудовании SD-карты, прошивке или программном обеспечении (драйвер, ОС) принудительным?

    Заменить слово несколькими строками с помощью sed?

    Мокито, Юнит и Весна

    FirebaseApp с именем не существует

    Каковы различия между «String» и «str» Rust?

    Приложение ссылается на непубличные селекторы в Payload / .app / : декодер

    Почему вложенные изображения Outlook 2007 больше оригинала?

    Solr Custom сходство

    Как издеваться над ограничениями реализации EntityFramework IQueryable

    Как скрыть файлы .class из диалога Open Resource в Eclipse?

    Скажите CMake, чтобы использовать компилятор C ++ для файлов C, поступающих из CMake?

    Обход проблемы из-за отсутствия оператора ‘nameof’ в C # для безопасного хранения данных по типу?

    Давайте будем гением компьютера.