Pergunta

Em outras palavras, como é que a implementação mantém o controle da contagem?

Existe um mapa-como objeto mantido que é acessível por todas as instâncias shared_ptr cuja chave é o endereço e o valor do ponteiro é o número de referências? Se eu tenho que implementar um shared_ptr, esta é a primeira idéia que vem à minha mente.

Existe uma possibilidade de um vazamento de memória no caso de estes ponteiros inteligentes de contagem de referência? Se sim, como posso evitá-los?

Foi útil?

Solução

Eu vi duas abordagens não-intrusivas diferentes para isso:

  1. O ponteiro inteligente aloca uma pequena bloco de memória para conter o contador de referência. Cada cópia do ponteiro inteligente, em seguida, recebe uma apontador para o objecto real e um ponteiro para a contagem de referência.
  2. Além de um ponteiro de objeto, cada ponteiro inteligente contém um anterior e seguinte ponteiro, assim formando uma lista duplamente ligado de ponteiros inteligentes para um determinado objeto. A contagem de referência é implícita na lista. Quando um inteligente ponteiro é copiado, ele adiciona-se a a lista. Após a destruição, cada ponteiro inteligente remove próprio a lista. Se ele é o último em a lista que, em seguida, libera o objeto referenciado também.

Se você vai aqui e vá até a parte inferior, há uma excelente diagrama que explica esses métodos muito mais claramente.

Outras dicas

Criação de um vazamento de memória com ponteiros inteligentes de contagem de referência é muito fácil. Apenas criar qualquer estrutura gráfico do tipo de objectos que tem um ciclo no gráfico. Os objectos no ciclo irá impedir o outro de ser libertado. Isso não pode ser resolvido automaticamente -. Por exemplo, quando você cria uma lista-link duplo você tem que tomar cuidado de não remover mais de um objeto de cada vez

Cada objeto ponteiro inteligente contém uma contagem de referência compartilhada -. Um para cada ponteiro bruto

Você poderia dar uma olhada este artigo . Esta implementação armazena estes em um objeto separado que é copiado ao redor. Você também pode dar uma olhada em documentação do impulso ou dê uma olhada na Wikipedia artigo sobre ponteiros inteligentes.

No. shared_ptr apenas manter um ponteiro adicional para contagem de referência.

Quando você faz cópia do objeto shared_ptr que copiar ponteiro com contagem de referências, aumentá-lo e copiar ponteiro no objeto contido.

Tanto quanto Lembro-me, houve o problema de ponteiro de contagem de referência tratado em um capítulo de Effective C ++.

Em princípio, você tem a classe ponteiro "light", que contém um ponteiro para uma classe segurando a referência que sabe para aumentar / diminuir de referência e destruir o objeto ponteiro. Que os pontos de classe contagem de referência para o objeto a ser referenciado.

Muitas respostas abordar a forma como a contagem de referência é armazenado (ele é armazenado em uma memória compartilhada para todos shared_ptr que mantenha o mesmo ponteiro nativo), mas a maioria iludir o problema de vazamentos.

A maneira mais fácil de vazamento de memória com referência contada ponteiros é a criação de ciclos. Como exemplo, uma lista duplamente ligada onde todos os ponteiros são shared_ptr com pelo menos dois elementos é garantido para não ser eliminado. Mesmo se ponteiros externos são liberados, os ponteiros internos ainda vai contar, e a contagem de referência não atingirá 0. Isto é, pelo menos, com a implementação mais ingênuo.

A solução mais fácil para o problema ciclo é misturar shared_ptr (referência contada ponteiros) com ponteiros fracos que não compartilham a propriedade do objeto.

ponteiros compartilhados irá compartilhar tanto o recurso (ponteiro) ea informação REFERENCE_COUNT adicional. Quando você usa ponteiros fracos, a contagem de referência é dobrada: há uma contagem de referência ponteiro compartilhada e uma contagem de referência ponteiro fraco. O recurso é liberado quando a contagem ponteiro compartilhada chega a 0, mas a informação REFERENCE_COUNT é deixado vivo até o último ponteiro fraco é liberado.

Na lista duplamente ligada, a referência externa é realizada em um shared_ptr, enquanto que as ligações internas são apenas weak_ptr. Sempre que não há referências externas (shared_ptr) os elementos da lista são liberados, excluir as referências fracas. No final todas as referências fracas foram apagados eo último ponteiro fraco para cada um dos recursos libera as informações REFERENCE_COUNT.

É menos confuso do que o texto acima parece ... Vou tentar novamente mais tarde.

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