Функция calloc() в C библиотека с програма ПРИМЕР

⚡ Умно обобщение

calloc() в C резервира множество съседни блокове памет в heap-а и инициализира всеки байт с нула, връщайки void указател, който позволява на програмите да създават чисти, готови за употреба масиви и структури от данни по време на изпълнение.

  • 🧠 Памет, инициализирана с нула: calloc() изчиства всеки разпределен байт до нула, за разлика от malloc(), който оставя непредсказуеми стойности като „боклук“.
  • 📦 Два аргумента: calloc(n, size) резервира n блока с дадения размер в една съседна област.
  • ⚠️ NULL проверка: Неуспешното разпределение връща NULL указател, така че валидирайте резултата, преди да го използвате.
  • 🆚 калок срещу малок: Изберете calloc() за чисти нулирани масиви и malloc() когато скоростта е по-важна от инициализацията.
  • 🧹 Освободете паметта: Освободете всеки блок calloc() с free(), за да предотвратите изтичане на памет.
  • 🤖 AI помощ: AI асистентите и GitHub Copilot изготвят calloc() извиквания и маркират липсващи free() оператори.

Функция calloc() в C

Какво е calloc в C?

Функцията calloc() в C е използвана за разпределяне на множество блокове памет с еднакъв размер. Това е функция за динамично разпределение на памет, която разпределя паметта на сложни структури от данни, като масиви и структури, и връща void указател към паметта. Calloc е съкращение от contiguous allocation (последователно разпределение).

Функция Malloc се използва за разпределяне на единичен блок пространство в паметта, докато функцията calloc в C се използва за разпределяне на множество блокове пространство в паметта. Всеки блок, разпределен от calloc в C програмирането, е с еднакъв размер.

Защо да използваме calloc() в C?

Обикновените променливи и масивите с фиксиран размер заключват размерите си при компилиране на програмата, което води до загуба на място, когато са необходими по-малко елементи, и се проваля напълно, когато са необходими повече. calloc() премахва това ограничение, като резервира памет по време на изпълнение и, за разлика от malloc(), изчиства всеки байт до нула, преди да върне блока обратно. Това прави calloc() естествения избор, когато една програма се нуждае от чиста, предвидима област от паметта за масив или структура, чийто размер е известен само докато кодът се изпълнява.

Динамичното разпределение с calloc() е подходящо за няколко често срещани ситуации:

  • Числови масиви, които трябва да започват от нула, като например броячи, хистограми или работещи акумулатори.
  • Структури от данни, където остатъчните стойности „боклук“ биха причинили фини, трудни за разбиранеtracи бъгове.
  • Bufferчиято дължина зависи от потребителския вход или файл, прочетен по време на изпълнение на програмата.
  • Блоковете са твърде големи за ограничения стек, тъй като calloc() черпи от много по-големия стек.

Тъй като резервираният блок е съседен и вече е нулиран, той може да се третира веднага като готов за употреба масив без отделен цикъл на инициализация.

calloc() Синтаксис:

ptr = (cast_type *) calloc (n, size);
  • Горният пример за оператор calloc в C се използва за разпределяне на n блока памет с еднакъв размер.
  • След като пространството в паметта е разпределено, всички байтове се инициализират до нула.
  • - показалка който в момента е в първия байт от разпределеното пространство на паметта, се връща.

Всеки път, когато има грешка при разпределяне на пространство в паметта, като например недостиг на памет, тогава се връща нулев указател, както е показано в примера calloc по-долу.

Как да използвате calloc

Програмата calloc по-долу в C изчислява сумата на аритметична последователност.

#include <stdio.h>
    int main() {
        int i, * ptr, sum = 0;
        ptr = calloc(10, sizeof(int));
        if (ptr == NULL) {
            printf("Error! memory not allocated.");
            exit(0);
        }
        printf("Building and calculating the sequence sum of the first 10 terms \ n ");
        for (i = 0; i < 10; ++i) { * (ptr + i) = i;
            sum += * (ptr + i);
        }
        printf("Sum = %d", sum);
        free(ptr);
        return 0;
    }

Резултат от calloc в C пример:

 
Building and calculating the sequence sum of the first 10 terms
Sum = 45

Разлика между calloc() и malloc()

calloc() и malloc() резервират памет в heap-а и връщат void указател или NULL при неуспех, но се различават по три практически начина, които определят кой от тях да се използва.

  • Инициализация: calloc() задава всеки байт в новия блок на нула, докато malloc() оставя съдържанието неинициализирано, така че блок malloc() съдържа непредсказуем боклук, докато програмата не запише в него.
  • Аргументи: calloc() приема два аргумента, броя на елементите и размера на всеки от тях, записан като calloc(n, size); malloc() приема един аргумент, общия брой байтове, записан като malloc(n * size).
  • Скорост: malloc() е малко по-бърза, защото пропуска стъпката на нулиране, поради което код, който незабавно презаписва паметта, често я предпочита.

И двете функции са декларирани в stdlib.h и освобождават паметта си с една и съща функция free(). Изберете calloc(), когато е важен чист, нулиран блок, и malloc(), когато е предпочитана сурова скорост и програмата сама се справя с инициализацията.

Как да освободим памет, разпределена от calloc()

Паметта, резервирана от calloc(), се намира в heap-а и никога не се освобождава автоматично. Когато една програма продължава да разпределя памет, без да я освобождава, тя бавно изразходва цялата налична памет – дефект, известен като изтичане на памет. Функцията free() връща завършен блок на системата, така че пространството да може да бъде използвано повторно при по-късни разпределения.

Функцията free() приема един аргумент, указателя, върнат от calloc(), и освобождава целия блок наведнъж:

int *ptr;
ptr = calloc(10, sizeof(int));
if (ptr != NULL) {
    /* use the allocated memory here */
    free(ptr);   /* release the block */
    ptr = NULL;  /* avoid a dangling pointer */
}

Следвайте тези правила, за да управлявате безопасно паметта на calloc():

  • Извиквайте free() точно веднъж за всяко успешно calloc(); освобождаването на един и същ блок два пъти води до неопределено поведение.
  • Задайте указателя на NULL след освобождаване, така че да не може да бъде използван повторно като висящ указател.
  • Никога не освобождава() указател, който calloc() не е върнал, включително такъв, изместен чрез аритметика на указателите.
  • Съпоставете всяко разпределение с освобождаване, преди показалецът да излезе извън обхвата.

Тъй като calloc() и malloc() черпят от един и същ heap, дисциплината за освобождаване е идентична и за двете функции: едно free() за всяко успешно разпределение и без достъп до блока след това. Keeping Разпределението и освобождаването в баланс е основният навик за ръчно управление на паметта в C и предотвратява както течове, така и сривове, причинени от повторно използване на вече върната памет.

Въпроси и Отговори

calloc() е деклариран в заглавката на стандартната библиотека stdlib.h, така че добавете #include в началото на изходния файл. Без него компилаторът може да предупреди за имплицитна декларация и да прочете погрешно върнатия указател.

Когато heap-ът не може да удовлетвори заявката, calloc() връща NULL указател вместо валиден адрес. Винаги сравнявайте резултата с NULL, преди да го използвате, защото разреференцирането на NULL води до неопределено поведение и обикновено води до срив на програмата.

Да. calloc() работи с всякакъв тип, включително структури и масиви от структури, като предава броя на елементите и размера на (sizeof(struct). Всеки член се нулира, което дава чисто начално състояние без цикъл на ръчна инициализация.

Да. realloc() приема всеки указател, върнат от calloc() или malloc() и увеличава или свива блока, запазвайки съществуващите данни. Новите байтове, добавени от realloc(), не се нулират, така че ги инициализирайте сами, ако е необходимо.

Резултатът е дефиниран от имплементацията: calloc() може да върне NULL или уникален указател, който не може да бъде дереференциран, но може безопасно да бъде предаден на free(). Третирайте и двата резултата като „няма използваема памет“ и избягвайте четене от него.

calloc() резервира една непрекъсната област, достатъчно голяма за всички заявени елементи, така че те да са разположени една до друга като клетки от масив. Името отразява този съседен, изчистен блок, позволявайки на аритметиката на показалеца да се движи надеждно през паметта.

Да. Асистентите за кодиране с изкуствен интелект изготвят calloc() извиквания, добавят NULL проверки и маркират липсващи free() извиквания или течове, и обясняват аритметиката на пойнтерите. Винаги компилирайте и тествайте генерирания код, преди да го доверите в продукция.

Копилот на GitHub предлага calloc(), sizeof() и съответстващи free() редове от коментар, описващ вашето намерение. RevПрегледайте всяко предложение за липсващи NULL проверки и течове, преди да компилирате.

Обобщете тази публикация с: