Teoricamente posso dizer que
free(ptr);
free(ptr);
é uma corrupção de memória, pois estamos liberando a memória que já foi liberada.
Mas e se
free(ptr);
ptr=NULL;
free(ptr);
Como o SO vai se comportar de maneira indefinida, não consigo fazer uma análise teórica real sobre o que está acontecendo. O que quer que eu esteja fazendo, isso é corrupção de memória ou não?
Liberar um ponteiro NULL é válido?
delete NULL
não é válido em C ++. delete pode ser aplicado a valores de ponteiro nulo de tipo concreto, mas não aNULL
.delete (int*) NULL
é legal, mas nãodelete NULL
.ptr
apontar para a memória e você não chamáfree
-lo, a memória vazará. Configurá-lo comoNULL
apenas perde o controle da memória e vaza. Septr
acontecer de serNULL
, chamarfree
é uma operação sem operação.free(ptr)
comptr = NULL
. Ninguém disse nada parecido.Respostas:
Consulte ISO-IEC 9899 .
Dito isso, ao observar diferentes bases de código na natureza, você notará que às vezes as pessoas fazem:
Isso ocorre porque alguns tempos de execução C (com certeza lembro que era o caso no PalmOS) travavam ao liberar um
NULL
ponteiro.Mas hoje em dia, acredito que seja seguro assumir que
free(NULL)
é um nop de acordo com as instruções do padrão.fonte
free(ptr)
ondeptr
é nulo não tem efeitos colaterais. Mas em qualquer caso, toda memória alocada usandomalloc()
oucalloc()
deve ser liberada depois usandofree()
free(NULL)
testando o ponteiroNULL
antes de chamarfree()
Todas as versões da biblioteca C em conformidade com os padrões tratam o Grátis (NULL) como um ambiente autônomo.
Dito isso, ao mesmo tempo havia algumas versões do free que travavam no free (NULL), por isso você pode ver algumas técnicas de programação defensiva recomendadas:
fonte
diz a documentação.
fonte
Lembro-me de trabalhar no PalmOS onde
free(NULL)
travou.fonte
NULL
foi uma das grandes diferenças da caixa de ferramentas Palm em comparação com a biblioteca padrão.Você pode excluir com segurança um ponteiro NULL. Nenhuma operação será realizada nesse caso. Em outras palavras, free () não faz nada em um ponteiro NULL.
fonte
Uso recomendado:
Vejo:
Quando você define o ponteiro para
NULL
depois,free()
pode chamáfree()
-lo novamente e nenhuma operação será realizada.fonte
free(NULL)
é perfeitamente legal em C, assim comodelete (void *)0
edelete[] (void *)0
é legal em C ++.BTW, liberar memória duas vezes geralmente causa algum tipo de erro de tempo de execução, então não corrompe nada.
fonte
delete 0
não é legal em C ++.delete
requer explicitamente uma expressão do tipo ponteiro. É legal aplicardelete
a um valor de ponteiro nulo digitado, mas não a0
(e não aNULL
).void*
: P Quais destruidores (s) ele deve ser executado?void *
contanto que seja um ponteiro nulo.buf1=malloc(X); free(buf1);buf2=malloc(X);free(buf1);
- aqui se você não tiver sorte, buf2 obteve exatamente o mesmo endereço que buf1, e você acidentalmente liberou buf1 duas vezes, então no segundo dia livre de buf1 você realmente liberou buf2 silenciosamente, sem casuing qualquer erro / falha / qualquer coisa (imidar). (mas provavelmente você ainda travará na próxima vez que tentar usar buf2 - e este cenário é muito improvável se você estiver executando em ASLR)free(ptr)
é salvo em C septr
forNULL
, entretanto, o que a maioria das pessoas não sabe é queNULL
não precisa ser igual a 0. Eu tenho um bom exemplo da velha escola: No C64, no endereço 0, há uma porta IO. Se você escreveu um programa em C acessando esta porta, você precisaria de um ponteiro cujo valor é 0. A biblioteca C correspondente teria que distinguir entre 0 eNULL
então.Atenciosamente.
fonte
não corrupção de memória, mas o comportamento depende da implementação. Por padrão, deve ser um código legal.
fonte
ptr está apontando para algum local da memória, digamos 0x100.
Quando você libera (ptr), basicamente você está permitindo que 0x100 seja usado pelo gerenciador de memória para ser usado para outra atividade ou processo e, em palavras simples, é a desalocação de recursos.
Quando você executa ptr = NULL, você está fazendo ptr apontar para um novo local (não vamos nos preocupar com o que é NULL). Ao fazer isso, você perdeu o controle dos dados de memória 0x100. Isso é o que é vazamento de memória.
Portanto, não é aconselhável usar ptr = NULL em um ptr válido.
Em vez disso, você pode fazer uma verificação de segurança usando:
if (ptr! = NULL) {free (ptr);}
Quando você libera (ptr) onde ptr já está apontando para NULL, ele não executa nenhuma operação. Portanto, é seguro fazê-lo.
fonte