Краткий ответ:
Это не так, просто в вашем случае он равен нулю.
(Также ваш тестовый пример не показывает, что данные равны нулю. Он показывает только, если один элемент равен нулю.)
Длинный ответ:
Когда вы звоните malloc()
, произойдет одно из двух:
- Перерабатывает память, которая была ранее выделена и освобождена из того же процесса.
- Запрашивает новые страницы из операционной системы.
В первом случае память будет содержать данные, оставшиеся от предыдущих выделений. Так что это не будет ноль. Это обычный случай при выполнении небольших выделений.
Во втором случае память будет от ОС. Это происходит, когда программе не хватает памяти - или когда вы запрашиваете очень большое выделение. (как в вашем примере)
Вот подвох: Память, поступающая из ОС, обнуляется по соображениям безопасности . *
Когда ОС предоставляет вам память, она могла быть освобождена из другого процесса. Так что память может содержать конфиденциальную информацию, такую как пароль. Поэтому, чтобы предотвратить чтение таких данных, ОС обнулит их, прежде чем они предоставят вам.
* Замечу, что в стандарте C об этом ничего не говорится. Это строго поведение ОС. Так что это обнуление может присутствовать или не присутствовать в системах, где безопасность не имеет значения.
Чтобы дать больше фона производительности для этого:
Как @R. упоминает в комментариях, это обнуление, поэтому вы всегда должны использовать calloc()
вместо malloc()
+ memset()
. calloc()
может воспользоваться этим фактом, чтобы избежать отдельного memset()
.
С другой стороны, это обнуление иногда является узким местом производительности. В некоторых числовых приложениях (например, FFT вне места) вам нужно выделить огромный кусок памяти. Используйте его для выполнения любого алгоритма, затем освободите его.
В этих случаях обнуление не требуется и составляет чистые накладные расходы.
Самый крайний пример, который я видел, это 20-секундные накладные расходы на обнуление для 70-секундной операции с чистым буфером 48 ГБ. (Примерно 30% накладных расходов.)
(Конечно: у машины не хватило пропускной способности памяти.)
Очевидное решение - просто повторно использовать память вручную. Но это часто требует прорыва через установленные интерфейсы. (особенно если это часть библиотечной процедуры)