Pergunta

Então eu tenho um ponteiro para uma série de ponteiros.Se eu deletar assim:

delete [] PointerToPointers;

Isso também excluirá todos os ponteiros apontados?Caso contrário, terei que percorrer todos os ponteiros e excluí-los também ou existe uma maneira mais fácil de fazer isso?Meu google-fu não parece me dar boas respostas para essa pergunta.

(E sim, eu sei que preciso usar um vetor.Esta é uma daquelas tarefas do tipo "atualizar o C++" na escola.)

Foi útil?

Solução

Sim, você tem que percorrer os ponteiros, excluindo individualmente.

Razão:E se outro código tivesse ponteiros para os objetos do seu array?O compilador C++ não sabe se isso é verdade ou não, então você precisa ser explícito.

Para uma "maneira mais fácil", duas sugestões:(1) Faça uma sub-rotina para esse fim para que pelo menos você não precise escrever o código mais de uma vez.(2) Use o paradigma de design do "ponteiro inteligente", onde você mantém uma matriz de objetos com contadores de referência e, em seguida, os objetos são excluídos quando não são mais referenciados por nenhum código.

Outras dicas

Concordo com Jason Cohen, embora possamos ser um pouco mais claros sobre o motivo da necessidade de excluir seus ponteiros do loop.Para cada alocação de memória "nova" ou dinâmica, é necessário "excluir" uma desalocação de memória.Algumas vezes, a "exclusão" pode estar oculta, como acontece com os smartpointers, mas ainda está lá.

int main()
{
  int *pI = new int;
  int *pArr = new int[10];

até agora no código alocamos dois pedaços de memória dinâmica.O primeiro é apenas um int geral, o segundo é um array de ints.

  delete pI;
  delete [] pArr;

essas instruções de exclusão limpam a memória que foi alocada pelos "novos"

  int ppArr = new int *[10];

  for( int indx = 0; indx < 10; ++indx )
  {
    ppArr[indx] = new int;
  }

Este pedaço de código está fazendo as duas alocações anteriores.Primeiro estamos criando espaço para nosso int em um array dinâmico.Em seguida, precisamos fazer um loop e alocar um int para cada ponto do array.

  for( int indx = 0; indx < 10; ++indx )
  {
    delete ppArr[indx];
  }
  delete [] ppArr;

Observe a ordem em que aloquei essa memória e depois a desaloquei na ordem inversa.Isso ocorre porque se fizéssemos o comando delete [] ppArr;primeiro perderíamos o array que nos diz quais são nossos outros ponteiros.Esse pedaço ou memória seria devolvido ao sistema e, portanto, não poderia mais ser lido de maneira confiável.

  int a=0;
  int b=1;
  int c=2;

  ppArr = new int *[3];

  ppArr[0] = &a;
  ppArr[1] = &b;
  ppArr[2] = &c;

Acho que isso também deveria ser mencionado.Só porque você está trabalhando com ponteiros não significa que a memória para a qual esses ponteiros apontam foi alocada dinamicamente.Isso quer dizer que só porque você tem um ponteiro não significa que ele necessariamente precise ser excluído.O array que criei aqui é alocado dinamicamente, mas os ponteiros apontam para instâncias locais de ints. Quando excluímos isso, precisamos apenas excluir o array.

  delete [] ppArr;

  return 0;

}

No final das contas, a memória alocada dinamicamente pode ser complicada e, de qualquer forma, você pode envolvê-la com segurança, como em um ponteiro inteligente ou usando contêineres stl em vez do seu próprio, pode tornar sua vida muito mais agradável.

Ver impulsionar contêiner de ponteiro para um contêiner que faz a exclusão automática dos ponteiros contidos para você, mantendo uma sintaxe muito próxima dos contêineres STL comuns.

Os ponteiros são basicamente apenas referências de memória e não pequenos objetos .net autolimpantes.A criação de destruidores adequados para cada classe tornará a exclusão um pouco mais limpa do que loops massivos em todo o código.

Vamos dar um exemplo do mundo real (pseudocodificado). Imagine que você tivesse uma aula como esta:

class Street
{
    public:
        Street();
        ~Street();
    private:
        int HouseNumbers_[];
}

typedef *Street StreetSign;

Se você tiver uma série de placas de rua e excluir sua série de placas de rua, isso não significa que você excluirá automaticamente as ruas.Eles ainda estão lá, tijolos e argamassa, só não têm mais aquelas placas apontando para eles.Você se livrou aqueles específicos instâncias de ponteiros para as ruas.

Uma matriz de ponteiros é (conceitualmente) um pouco como uma matriz de números inteiros, é uma matriz de números que representa as localizações de memória de vários objetos.Não são os objetos em si.

Se você excluir[] o array de ponteiros, tudo o que você fez foi deletar um array de inteiros.

Acho que você vai ter que dar uma volta, infelizmente.

Não sei por que isso foi respondido de maneira tão confusa.

Se você excluir a variedade de ponteiros, libertará a memória usada para uma matriz de INTs geralmente.
um ponteiro para um objeto é um número inteiro contendo o endereço.

Você excluiu vários endereços, mas nenhum objeto.

O Exclete não se importa com o conteúdo de um espaço de memória, ele chama um (s) destruidor (s) e marca o MEM como gratuito.

Não se importa que apenas exclua um monte de endereços de objetos, apenas vê Ints.

É por isso que você precisa percorrer o array primeiro!e ligue para excluir todos os elementos, você pode excluir o armazenamento da própria matriz.

Bem agora meu a resposta ficou um pouco longa.......estranho...;)

Editar:A resposta de Jason não está errada, apenas não acerta o alvo.Nem o compilador nem nada em C (++) se preocupam com você excluindo coisas que são apontadas em outro lugar.Você pode simplesmente fazer isso.Outras peças do programa que tentam usar os objetos excluídos se transformarão em você.Mas ninguém vai te atrapalhar.Também não será um problema destruir uma variedade de ponteiros para objetos, quando os objetos são referenciados em outros lugares.

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