Alocação dinâmica de memória em C usando funções malloc(), calloc()

Antes de aprender a alocação de memória dinâmica C, vamos entender:

Como funciona o gerenciamento de memória em C?

Quando você declara uma variável usando um tipo de dados básico, o compilador C aloca automaticamente espaço de memória para a variável em um conjunto de memória chamado pilha.

Por exemplo, uma variável float normalmente ocupa 4 bytes (de acordo com a plataforma) quando é declarada. Podemos verificar essas informações usando o tamanho operador conforme mostrado no exemplo abaixo

#include <stdio.h>
int main() { float x; printf("The size of float is %d bytes", sizeof(x)); return 0;}

A saída será:

 The size of float is 4 bytes

Além disso, um array com um tamanho especificado é alocado em blocos contíguos de memória, cada bloco tem o tamanho de um elemento:

#include <stdio.h>
int main() { float arr[10];
printf("The size of the float array with 10 element is %d", sizeof(arr)); return 0;}

O resultado é:

 The size of the float array with 10 element is 40

Conforme aprendido até agora, ao declarar um tipo de dados básico ou um array, a memória é gerenciada automaticamente. No entanto, existe um processo para alocação de memória em C que permitirá implementar um programa no qual o tamanho do array está indeciso até que você execute seu programa (tempo de execução). Este processo é denominado “Alocação dinâmica de memória. "

Alocação dinâmica de memória em C

Alocação de memória dinâmica é a alocação manual e liberação de memória de acordo com suas necessidades de programação. A memória dinâmica é gerenciada e servida com ponteiros que apontam para o espaço de memória recém-alocado em uma área que chamamos de heap.

Agora você pode criar e destruir um array de elementos dinamicamente em tempo de execução sem problemas. Resumindo, o gerenciamento automático de memória usa a pilha e a alocação dinâmica de memória C usa o heap.

O biblioteca possui funções responsáveis ​​pelo gerenciamento dinâmico de memória.

função Propósito
malloc () Aloca a memória do tamanho solicitado e retorna o ponteiro para o primeiro byte do
espaço alocado.
calloc () Aloca o espaço para elementos de uma matriz. Inicializa os elementos para zero e retorna um ponteiro para a memória.
realloc () É usado para modificar o tamanho do espaço de memória alocado anteriormente.
Livre() Libera ou esvazia o espaço de memória alocado anteriormente.

Vamos discutir as funções acima com sua aplicação

função malloc() em C

A função C malloc() significa alocação de memória. É uma função usada para alocar um bloco de memória dinamicamente. Ele reserva espaço de memória de tamanho especificado e retorna o ponteiro nulo apontando para o local da memória. O ponteiro retornado geralmente é do tipo void. Isso significa que podemos atribuir a função C malloc() a qualquer ponteiro.

Sintaxe da função malloc():

ptr = (cast_type *) malloc (byte_size);

Aqui,

  • ptr é um ponteiro de cast_type.
  • A função C malloc() retorna um ponteiro para a memória alocada de byte_size.

Exemplo de malloc():

Example: ptr = (int *) malloc (50)

Quando esta instrução é executada com sucesso, um espaço de memória de 50 bytes é reservado. O endereço do primeiro byte do espaço reservado é atribuído ao ponteiro ptr do tipo int.

Considere outro exemplo:

#include <stdlib.h>
int main(){
int *ptr;
ptr = malloc(15 * sizeof(*ptr)); /* a block of 15 integers */
    if (ptr != NULL) {
      *(ptr + 5) = 480; /* assign 480 to sixth integer */
      printf("Value of the 6th integer is %d",*(ptr + 5));
    }
}

Saída:

Value of the 6th integer is 480

Função C malloc()

  1. Observe que tamanho de(*ptr) foi usado em vez de tamanho de (int) para tornar o código mais robusto quando a declaração *ptr for convertida posteriormente para um tipo de dados diferente.
  2. A alocação poderá falhar se a memória não for suficiente. Neste caso, ele retorna um ponteiro NULL. Portanto, você deve incluir código para verificar um ponteiro NULL.
  3. Tenha em mente que a memória alocada é contígua e pode ser tratada como um array. Podemos usar aritmética de ponteiro para acessar os elementos do array em vez de usar colchetes []. Aconselhamos usar + para se referir a elementos do array porque usar incrementação ++ ou += altera o endereço armazenado pelo apontador.

A função Malloc() também pode ser usada com o tipo de dados de caractere, bem como com tipos de dados complexos, como estruturas.

função free() em C

A memória para variáveis é automaticamente desalocado em tempo de compilação. Na alocação dinâmica de memória, você deve desalocar memória explicitamente. Caso contrário, você poderá encontrar um erro de falta de memória.

O grátis() A função é chamada para liberar/desalocar memória em C. Ao liberar memória em seu programa, você disponibiliza mais memória para uso posterior.

Por exemplo:

#include <stdio.h>
int main() {
int* ptr = malloc(10 * sizeof(*ptr));
if (ptr != NULL){
  *(ptr + 2) = 50;
  printf("Value of the 2nd integer is %d",*(ptr + 2));
}
free(ptr);
}

Saída:

 Value of the 2nd integer is 50

Função calloc() em C

A função C calloc() significa alocação contígua. Esta função é usada para alocar vários blocos de memória. É uma função de alocação dinâmica de memória que é usada para alocar memória para estruturas de dados complexas, como arrays e estruturas.

A função Malloc() é usada para alocar um único bloco de espaço de memória, enquanto calloc() em C é usada para alocar vários blocos de espaço de memória. Cada bloco alocado pela função calloc() é do mesmo tamanho.

Sintaxe da função calloc():

ptr = (cast_type *) calloc (n, size);
  • A instrução acima é usada para alocar n blocos de memória do mesmo tamanho.
  • Depois que o espaço de memória é alocado, todos os bytes são inicializados em zero.
  • O ponteiro que está atualmente no primeiro byte do espaço de memória alocado é retornado.

Sempre que houver um erro na alocação de espaço de memória, como falta de memória, um ponteiro nulo será retornado.

Exemplo de calloc():

O programa abaixo calcula a soma de uma sequência aritmética.

#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;
    }

Resultado:

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

calloc() vs. malloc(): principais diferenças

A seguir está a principal diferença entre malloc() versus calloc() em C:

A função calloc() é geralmente mais adequada e eficiente do que a função malloc(). Embora ambas as funções sejam usadas para alocar espaço de memória, calloc() pode alocar vários blocos ao mesmo tempo. Você não precisa solicitar um bloco de memória todas as vezes. A função calloc() é usada em estruturas de dados complexas que requerem maior espaço de memória.

O bloco de memória alocado por um calloc() em C é sempre inicializado em zero, enquanto na função malloc() em C, ele sempre contém um valor lixo.

função realloc() em C

Usando o C realloc () função, você pode adicionar mais tamanho de memória à memória já alocada. Ele expande o bloco atual, deixando o conteúdo original como está. realloc() em C significa realocação de memória.

realloc() também pode ser usado para reduzir o tamanho da memória alocada anteriormente.

Sintaxe da função realloc():

ptr = realloc (ptr,newsize);

A instrução acima aloca um novo espaço de memória com um tamanho especificado na variável newsize. Após executar a função, o ponteiro retornará ao primeiro byte do bloco de memória. O novo tamanho pode ser maior ou menor que a memória anterior. Não podemos ter certeza de que o bloco recém-alocado apontará para o mesmo local do bloco de memória anterior. Esta função irá copiar todos os dados anteriores na nova região. Isso garante que os dados permanecerão seguros.

Exemplo de realloc():

#include <stdio.h>
int main () {
   char *ptr;
   ptr = (char *) malloc(10);
   strcpy(ptr, "Programming");
   printf(" %s,  Address = %u\n", ptr, ptr);

   ptr = (char *) realloc(ptr, 20); //ptr is reallocated with new size
   strcat(ptr, " In 'C'");
   printf(" %s,  Address = %u\n", ptr, ptr);
   free(ptr);
   return 0;
}

Sempre que realloc() em C resulta em uma operação malsucedida, ele retorna um ponteiro nulo e os dados anteriores também são liberados.

Matrizes Dinâmicas em C

Um array dinâmico em C permite que o número de elementos cresça conforme necessário. C A matriz dinâmica é amplamente utilizada em algoritmos de ciência da computação.

No programa a seguir, criamos e redimensionamos um array dinâmico em C

#include <stdio.h>
    int main() {
        int * arr_dynamic = NULL;
        int elements = 2, i;
        arr_dynamic = calloc(elements, sizeof(int)); //Array with 2 integer blocks
        for (i = 0; i < elements; i++) arr_dynamic[i] = i;
        for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);
        elements = 4;
        arr_dynamic = realloc(arr_dynamic, elements * sizeof(int)); //reallocate 4 elements
        printf("After realloc\n");
        for (i = 2; i < elements; i++) arr_dynamic[i] = i;
        for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);
        free(arr_dynamic);
    }

Resultado do programa C Dynamic array na tela:

 
arr_dynamic[0]=0
arr_dynamic[1]=1
After realloc
arr_dynamic[0]=0
arr_dynamic[1]=1
arr_dynamic[2]=2
arr_dynamic[3]=3

Resumo

  • Podemos gerenciar a memória dinamicamente criando blocos de memória conforme necessário no heap
  • Na alocação dinâmica de memória C, a memória é alocada em tempo de execução.
  • A alocação dinâmica de memória permite manipular strings e arrays cujo tamanho é flexível e pode ser alterado a qualquer momento em seu programa.
  • É necessário quando você não tem ideia de quanta memória uma determinada estrutura irá ocupar.
  • Malloc() em C é uma função de alocação dinâmica de memória que significa alocação de memória que bloqueia blocos de memória com tamanho específico inicializados com um valor lixo
  • Calloc() em C é uma função de alocação de memória contígua que aloca vários blocos de memória por vez inicializados em 0
  • Realloc() em C é usado para realocar memória de acordo com o tamanho especificado.
  • A função Free() é usada para limpar a memória alocada dinamicamente.