No seu exemplo, myApple
tem o valor especial null
(normalmente todos os zero bits) e, portanto, não faz referência a nada. O objeto ao qual ele se referiu originalmente agora está perdido no heap. Não há como recuperar sua localização. Isso é conhecido como vazamento de memória em sistemas sem coleta de lixo.
Se você originalmente definir 1000 referências como nulas, terá espaço para apenas 1000 referências, geralmente 1000 * 4 bytes (em um sistema de 32 bits, duas vezes o número em 64). Se essas 1.000 referências apontarem originalmente para objetos reais, você alocou 1000 vezes o tamanho de cada objeto, mais espaço para as 1000 referências.
Em algumas linguagens (como C e C ++), os ponteiros sempre apontam para alguma coisa, mesmo quando "não inicializados". O problema é se o endereço que eles mantêm é legal para o seu programa acessar. O endereço especial zero (aka null
) não é deliberadamente mapeado no seu espaço de endereço, portanto, uma falha de segmentação é gerada pela unidade de gerenciamento de memória (MMU) quando é acessada e seu programa trava. Porém, como o endereço zero não é deliberadamente mapeado, torna-se um valor ideal a ser usado para indicar que um ponteiro não está apontando para nada, daí seu papel como null
. Para completar a história, conforme você aloca memória com new
oumalloc()
, o sistema operacional configura a MMU para mapear páginas da RAM para o seu espaço de endereço e elas se tornam utilizáveis. Ainda existem tipicamente amplos intervalos de espaço de endereço que não são mapeados e, portanto, também levam a falhas de segmentação.
std::shared_ptr<Apple>
é um exemplo que nem GC nem vazaApple
quando zerado.shared_ptr
apenas um formulário básico para coleta de lixo? O GC não exige que haja um "coletor de lixo" separado, apenas essa coleta de lixo ocorre.A resposta depende do idioma que você está usando.
C / C ++
Em C e C ++, a palavra-chave era NULL, e o que realmente era NULL era 0. Foi decidido que "0x0000" nunca seria um ponteiro válido para um objeto, e esse é o valor que é atribuído para indicar que ele é. não é um ponteiro válido. No entanto, é completamente arbitrário. Se você tentasse acessá-lo como um ponteiro, ele se comportaria exatamente como um ponteiro para um objeto que não existe mais na memória, causando uma exceção de ponteiro inválida. O ponteiro em si ocupa memória, mas não mais do que um objeto inteiro. Portanto, se você tiver 1000 ponteiros nulos, será equivalente a 1000 números inteiros. Se alguns desses ponteiros apontarem para objetos válidos, o uso da memória seria equivalente a 1000 números inteiros mais a memória contida nesses ponteiros válidos. Lembre-se de que em C ou C ++,não implica que a memória foi liberada, portanto, você deve excluir explicitamente esse objeto usando dealloc (C) ou delete (C ++).
Java
Diferentemente de C e C ++, em Java nulo é apenas uma palavra-chave. Em vez de gerenciar nulo como um ponteiro para um objeto, ele é gerenciado internamente e tratado como um literal. Isso eliminou a necessidade de vincular ponteiros como tipos inteiros e permite que o Java abstraia completamente os ponteiros. No entanto, mesmo que o Java oculte melhor, eles ainda são ponteiros, o que significa que 1000 ponteiros nulos ainda consomem o equivalente a 1000 números inteiros. Obviamente, quando apontam para objetos, como C e C ++, a memória é consumida por esses objetos até que não haja mais indicadores sobre eles; no entanto, ao contrário de C e C ++, o coletor de lixo o pega na próxima passagem e libera a memória, sem exigir que você tenha que rastrear quais objetos estão liberados e quais não, na maioria dos casos (a menos que você tenha motivos para fazer referência fraca a objetos, por exemplo).
fonte
NULL
( não uma palavra-chave, a propósito) são tratados como se fossem zero bits. Mas eles não precisam ser implementadas, como tal, e de fato algumas implementações obscuros fazer uso diferentes de zero ponteiros nulos. Se eu escreverif (myptr == 0)
, o compilador fará a coisa correta, mesmo que o ponteiro nulo seja representado internamente por0xabcdef
.0
é uma constante de ponteiro nulo, mas isso não significa quemyptr == 0
verifica se todos os bits demyptr
são zero.NULL
macro, em vez de falar sobre o "ponteiro nulo" e mencionar explicitamente que "o literal-0 pode ser implicitamente convertido em um ponteiro nulo".Um ponteiro é simplesmente uma variável que é principalmente de um tipo inteiro. Ele especifica um endereço de memória em que o objeto real está armazenado.
A maioria dos idiomas permite acessar membros do objeto através desta variável de ponteiro:
O compilador sabe como acessar os membros de um
Apple
. "Segue" o ponteiro paramyApple
o endereço e recupera o valor doappleInt
Se você atribuir o ponteiro nulo a uma variável de ponteiro, faça o ponteiro apontar para nenhum endereço de memória. (O que torna o acesso do membro impossível.)
Para cada ponteiro, você precisa de memória para manter o valor inteiro do endereço de memória (principalmente 4 bytes em sistemas de 32 bits, 8 bytes em sistemas de 64 bits). Isso também é verdadeiro para ponteiros nulos.
fonte
Exemplo rápido (note que os nomes variáveis não são armazenados):
Felicidades.
fonte