Corrigir erro de Ponteiro Inválido Livre em C

Jinku Hu 12 outubro 2023
  1. Não free Ponteiros que apontam para locais de memória não-dinâmica
  2. Não free de apontadores que já tenham sido libertados
Corrigir erro de Ponteiro Inválido Livre em C

Este artigo irá introduzir múltiplos métodos sobre como corrigir o erro de ponteiro inválido “livre” em C.

Não free Ponteiros que apontam para locais de memória não-dinâmica

A chamada de função free só deve ser utilizada para desalocar a memória a partir das indicações que tenham sido devolvidas pelas funções malloc, calloc, ou realloc. O código seguinte mostra o cenário em que ao ponteiro char* é atribuído um valor retornado da chamada malloc, mas mais tarde no bloco else, o mesmo ponteiro é reatribuído com uma string literal. Isto significa que a variável c_str aponta para o local que não é uma região de memória dinâmica; assim, não é permitido passar para a função free. Como resultado, quando o próximo exemplo é executado, e o programa atinge a chamada de função free, é abortado, e o erro free(): ponteiro inválido é exibido.

Note-se que não se deve reatribuir os apontadores a localizações de memória dinâmica com endereços diferentes, a menos que ainda existam outras variáveis do ponteiro que apontem para a localização original. Finalmente, só se deve chamar a função free em apontadores que apontem para a memória de pilha.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, const char *argv[]) {
  char *c_str = NULL;
  size_t len;

  if (argc != 2) {
    printf("Usage: ./program string\n");
    exit(EXIT_FAILURE);
  }

  if ((len = strlen(argv[1])) >= 4) {
    c_str = (char *)malloc(len);

    if (!c_str) {
      perror("malloc");
    }

    strcpy(c_str, argv[1]);
    printf("%s\n", c_str);
  } else {
    c_str = "Some Literal String";
    printf("%s\n", c_str);
  }
  free(c_str);

  exit(EXIT_SUCCESS);
}

Não free de apontadores que já tenham sido libertados

Outro erro comum quando se utiliza a memória dinâmica é chamar a função free nos ponteiros que já foram libertados. Este cenário é mais provável quando existem múltiplas variáveis de apontadores apontando para a mesma região de memória dinâmica. O seguinte código de amostra demonstra um desses casos possíveis, em que a mesma localização é libertada em âmbitos diferentes.

Note-se que este exemplo é um único programa curto de ficheiro, e será fácil diagnosticar um problema como este, mas nas bases de código maiores, poderá ser difícil rastrear a fonte sem programas de inspectores externos que façam análises estáticas.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, const char *argv[]) {
  char *c_str = NULL;
  size_t len;

  if (argc != 2) {
    printf("Usage: ./program string\n");
    exit(EXIT_FAILURE);
  }
  char *s = NULL;

  if ((len = strlen(argv[1])) >= 4) {
    c_str = (char *)malloc(len);
    s = c_str;

    if (!c_str) {
      perror("malloc");
    }

    strcpy(c_str, argv[1]);
    printf("%s\n", c_str);
    free(c_str);
  } else {
    c_str = "Some Literal String";
    printf("%s\n", c_str);
  }
  free(s);

  exit(EXIT_SUCCESS);
}
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Artigo relacionado - C Pointer