Intereting Posts
Как изменить имя дочернего процесса без исключения функций exec? структурная путаница Несколько сокетов для подключения клиентов к fgets () не работает, поскольку я ожидаю, что он Как читать двоичный файл в c? (видео, изображения или текст) Int в правило преобразования символов в C, когда int находится вне диапазона char C: преобразование типа при передаче аргумента при вызове функции Скомпилировать программу C с помощью dlopen и dlsym с помощью -fPIC Как «многопоточный» код sendfile64 копирует только 2GB Почему мой маленький листок QUOTE? Необходимо знать, когда между двумя разделителями токенов нет данных, используя strtok () Как захватить весь локальный запрос HTTP и извлечь URL-адрес с помощью c? Как создать случайное число из целого диапазона int в C? Является ли `* ((* (& array + 1)) – 1)` безопасным для использования, чтобы получить последний элемент автоматического массива?

C: malloc, кажется, выделяет больше, чем я запрашиваю (массив)

Привет, у меня есть этот вопрос: почему, когда я выделяю память с помощью malloc для массива с плавающей точкой, он выделяет больше пространства, которое я запрашиваю? Например, в этом коде я пытаюсь выделить массив с плавающей запятой из десяти ячеек, но если я попытаюсь получить доступ к другим ячейкам, то я не получу ошибки segfault:

#include  #include  #include  float *fk_array; int main(int argc, char** argv){ fk_array = (float *) malloc(10 * sizeof(float)); int i; fk_array[9] = 2.23; fk_array[15] = 0.3; for(i = 0; i<20 ; i++) printf("%f\n",fk_array[i]); free(fk_array); return 1; } 

Он возвращает меня:

 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.230000 0.000000 0.000000 0.000000 0.000000 0.000000 0.300000 0.000000 0.000000 0.000000 0.000000 

Где я ошибаюсь?

При вызове malloc дополнительное пространство может использоваться для хранения метаданных о выделенном блоке, таких как его размер и информация о других выделенных блоках. Иногда реализация предпочитает выделенные блоки с определенными интервалами (например, кратные 4 или 8 байтов). Однако вы не должны зависеть от того, сколько пространства будет согласовано каждый раз, когда вы вызываете malloc ; используйте только то, что вы специально запросили, или вы можете переписать другую важную информацию.

Дополнительную информацию см. В ответах на следующие вопросы:

  • Как работают free и malloc в C?
  • Почему malloc выделяет другое количество байтов, чем запрошено?

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

Я не удивлюсь, если выделение памяти кучи не попадет в определенные правила процессора, которые должны быть выровнены по длинной, квадратной или другой границе.

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

Вы можете получить только ошибку сегментации, если чтение или запись попадает на неправильную страницу . Страница обычно 4KiB.

Системный вызов malloc() может зарезервировать немного больше места по сравнению с запросом, и он оставляет несколько слов памяти перед блоком для ведения бухгалтерского учета, но что ваша программа не убивается, когда доступ к fk_array[15] не означает, что это не было доступа за пределами зарезервированного для него блока. Скорее всего, ОС просто этого не заметила. Если бы вы выделили другой массив после выделения fk_array , у вас был бы шанс заметить, что он меняется.