calloc
дает вам кучу dynamically allocated нулевую зону памяти (в ваш bar2
). Но автоматическая переменная (например, bar
, при условии, что ее объявление находится внутри функции) назначается на call stack. См. Также calloc(3)
В C вам необходимо явно указать free
выделенную памятью. Но данные, выделенные стекем, выворачиваются, когда возвращается функция.
Rerad также wikipage на C dynamic memory allocation, а также на garbage collection. Reference counting - широко используемый метод в C и C++, и его можно рассматривать как форму GC. Подумайте о circular references, с ними сложно справиться.
Boehm conservative GC может использоваться в программах на C.
Обратите внимание, что жизнеспособность зоны памяти является глобальной базой . Обычно вы не можете утверждать, что зона предоставления принадлежит определенной функции (или библиотеке). Но вы можете принять соглашения об этом.
При кодировании функции, возвращающей указатель на кучу (т. Е. Некоторый указатель на динамическое хранилище), вы должны документировать этот факт и решать, кто его освобождает.
Об инициализации: calloc
указатель обнуляется (когда calloc
успешно). Автоматическая переменная, инициализированная как {0}
, также обнуляется. На практике некоторые реализации могут calloc
по-разному большие объекты (путем запроса целых нулевых страниц из ядра для них, например, с mmap(2)) и небольших объектов (путем повторного использования, если доступно, ранее free
-d зоны и обнуления). нулевая зона использует быстрый эквивалент memset(3)
PS. Я игнорирую странные машины, на которых вся нулевая бит-зона памяти не является очищенными данными для стандарта C, то есть {0}
. Я не знаю таких машин на практике, даже если я знаю, что они в принципе возможны (и теоретически указатель NULL
может не быть полностью нулевым битом)
BTW, компилятор может оптимизировать все -zero локальная структура (и, возможно, не выделяет ее вообще в стеке, поскольку она будет вписываться в регистры).
Теперь мне интересно: что, если мы заменим 'calloc' на' alloca', а затем 'memset' на ноль? Тогда будет ли какая-то значительная разница? – MooseBoys
'alloca' является нестандартным. Кроме того, 'alloca' выделяет в стеке, а не в куче, и не сообщает об ошибках (выделение большего объема памяти, чем доступно, имеет неопределенное поведение и, вероятно, приведет к сбою вашей программы, прежде чем она сможет обнаружить ошибку). –
«он не сообщает об ошибках». Также не вызывает функцию, которая также может взорвать стек. Техническая бородавка на стандарте заключается в том, что она не гарантирует никаких гарантий на глубину стека, поэтому практически нет программы C строго соответствует. –