Corrigir erro de Ponteiro Inválido Livre em C
-
Não
free
Ponteiros que apontam para locais de memória não-dinâmica -
Não
free
de apontadores que já tenham sido libertados
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);
}
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