Pergunta

Ignorando estilo de programação e design, é "seguro" para chamar de eliminação num variável alocada na pilha?

Por exemplo:

   int nAmount;
   delete &nAmount;

ou

class sample
{
public:
    sample();
    ~sample() { delete &nAmount;}
    int nAmount;
}
Foi útil?

Solução

Sem , não é seguro para chamar delete em uma variável alocada-stack. Você só deve chamar delete em coisas criadas por new.

  • Para cada malloc ou calloc, deve haver exatamente um free.
  • Para cada new deve haver exatamente um delete.
  • Para cada new[] deve haver exatamente um delete[].
  • Para cada alocação de pilha, não deve haver liberação explícita ou exclusão. O destruidor é chamado automaticamente, quando aplicável.

Em geral, você não pode misturar e combinar qualquer um destes, por exemplo, não free-ing ou delete[]-ing um objecto new. Fazer isso resulta em um comportamento indefinido.

Outras dicas

Bem, vamos tentar:

jeremy@jeremy-desktop:~$ echo 'main() { int a; delete &a; }' > test.cpp
jeremy@jeremy-desktop:~$ g++ -o test test.cpp
jeremy@jeremy-desktop:~$ ./test
Segmentation fault

Então, aparentemente não é seguro em tudo.

Tenha em mente que quando você alocar um bloco de memória usando novo (ou malloc para que o assunto), o bloco real de memória alocada será maior do que o que você pediu. O bloco de memória também vai conter algumas informações de contabilidade para que quando você liberar o bloco, ele pode facilmente ser colocado de volta para a piscina livre e, possivelmente, ser fundiram com blocos livres adjacentes.

Quando você tentar libertar qualquer memória que você não recebe de novo, que a informação da contabilidade não vai estar lá, mas o sistema irá agir como ele é e os resultados vão ser imprevisível (geralmente ruim).

Sim, é um comportamento indefinido: passando para delete qualquer coisa que não veio de new é UB:

padrão C ++, seção 3.7.3.2.3: O valor do primeiro argumento fornecido a uma das funções Thea desalocação fornecidos na biblioteca padrão pode ser um valor de ponteiro null; Se assim for, e se a função de desalocação é fornecido na biblioteca padrão, a chamada para a função de desalocação não tem efeito. Caso contrário, o valor fornecido para operator delete(void*) na biblioteca padrão deve ser um dos valores devolvidos por uma chamada anterior de qualquer operator new(std::size_t) ou operator new(std::size_t, const std::nothrow_t&) na biblioteca padrão.

As consequências de um comportamento indefinido são, bem, indefinido. "Nada acontece" é como consequência uma válida quanto qualquer outra coisa. No entanto, normalmente é "nada acontece imediatamente":. Desalocá um bloco de memória inválido pode ter consequências graves em chamadas subseqüentes para o alocador

Depois de jogar um pouco com g ++ 4.4 no Windows, eu tenho resultados muito interessantes:

  1. chamando de exclusão em um variável de pilha não parece fazer nada. Sem erros jogar, mas eu posso acessar a variável sem problemas após a exclusão.

  2. Ter uma classe com um método com delete this elimina com sucesso o objeto se ele é alocado no heap, mas não se isso é alocado na pilha (se é na pilha, nada acontece).

Ninguém pode saber o que acontece. Isso invoca um comportamento indefinido, então literalmente qualquer coisa pode acontecer. Não faça isso.

Não, Memória alocada usando novo deve ser eliminada utilizando operador delete e que alocado usando malloc devem ser excluídos usando livre. E não há necessidade de desalocar a variável que são alocados na pilha.

Um anjo perde suas asas ... Você só pode chamar delete em um ponteiro alocado com new, caso contrário, você obtém um comportamento indefinido.

aqui a memória é alocada usando pilha assim não há necessidade para excluí-lo exernally mas se você tiver allcoted dinamicamente

como int * a = new int ()

então você tem que fazer apagar um e não excluir e um (a si mesmo é um ponteiro), porque a memória é alocada de loja livre.

Você já respondeu a pergunta a si mesmo. delete só deve ser usado para ponteiros optained através new. Fazer qualquer outra coisa é um comportamento indefinido pura e simples.

Portanto, não há realmente nenhuma dizendo o que acontece, qualquer coisa, desde a multa de trabalho de código através de cair para apagar seu disco rígido é um resultado válido de fazer isso. Então, por favor não fazer isso .

UB é porque você não deve chamar de exclusão em um item que não foi alocada dinamicamente com o novo. É simples assim.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top