В вашем примере myApple
есть специальное значение null
(обычно все нулевые биты), и поэтому ничего не ссылается. Объект, на который он первоначально ссылался, теперь теряется в куче. Нет способа узнать его местоположение. Это известно как утечка памяти в системах без сборки мусора.
Если вы изначально установили 1000 ссылок на ноль, то у вас будет место только для 1000 ссылок, обычно 1000 * 4 байта (в 32-битной системе, вдвое больше, чем в 64). Если эти 1000 ссылок изначально указывали на реальные объекты, то вы выделили 1000-кратный размер каждого объекта плюс пространство для 1000 ссылок.
В некоторых языках (например, C и C ++) указатели всегда указывают на что-то, даже когда они неинициализированы. Вопрос в том, является ли адрес, который они имеют, законным для вашей программы. Специальный нулевой адрес (он же null
) преднамеренно не отображается в вашем адресном пространстве, поэтому блок управления памятью (MMU) генерирует ошибку сегментации при обращении к ней и сбое вашей программы. Но поскольку нулевой адрес намеренно не отображается, он становится идеальным значением для указания того, что указатель ни на что не указывает, поэтому его роль как null
. Для завершения истории, как вы выделяете память с new
илиmalloc()
операционная система настраивает MMU для отображения страниц оперативной памяти в ваше адресное пространство, и они становятся пригодными для использования. Обычно по-прежнему существуют огромные диапазоны адресного пространства, которые не отображаются, что также приводит к ошибкам сегментации.
std::shared_ptr<Apple>
является примером, который не является ни GC, ни утечкой,Apple
когда обнуляется.shared_ptr
просто форма для сбора мусора? GC не требует наличия отдельного «сборщика мусора», только сбор мусора.Ответ зависит от языка, который вы используете.
C / C ++
В C и C ++ ключевым словом было NULL, а в действительности NULL было 0. Было решено, что «0x0000» никогда не будет действительным указателем на объект, и поэтому это значение присваивается, чтобы указать, что оно неверный указатель Тем не менее, это совершенно произвольно. Если вы попытаетесь получить к нему доступ как указатель, он будет вести себя точно так же, как указатель на объект, которого больше нет в памяти, что приведет к возникновению исключения недопустимого указателя. Сам указатель занимает память, но не более чем целочисленный объект. Следовательно, если у вас есть 1000 нулевых указателей, это эквивалент 1000 целых чисел. Если некоторые из этих указателей указывают на допустимые объекты, то использование памяти будет эквивалентно 1000 целым числам плюс память, содержащаяся в этих допустимых указателях. Помните, что в C или C ++,не означает, что память была освобождена, поэтому вы должны явно удалить этот объект, используя dealloc (C) или delete (C ++).
Джава
В отличие от C и C ++, в Java null является просто ключевым словом. Вместо того, чтобы управлять нулем как указатель на объект, он управляется внутри и обрабатывается как литерал. Это устраняет необходимость связывать указатели как целочисленные типы и позволяет Java полностью абстрагировать указатели. Однако даже если Java скрывает это лучше, они все еще являются указателями, то есть 1000 нулевых указателей по-прежнему потребляют эквивалент 1000 целых чисел. Очевидно, что когда они указывают на объекты, во многом как на C и C ++, эти объекты используют память до тех пор, пока на них не ссылаются указатели, однако, в отличие от C и C ++, сборщик мусора забирает их на следующем проходе и освобождает память, не требуя, чтобы вам приходилось отслеживать, какие объекты освобождены, а какие нет, в большинстве случаев (если, например, у вас нет причин для слабой ссылки на объекты).
источник
NULL
( между прочим, не ключевое слово) обрабатываются так, как если бы они были нулевыми битами. Но они не должны быть реализованы как таковые, а на самом деле некоторые неясные реализации делают использование ненулевых указателей неопределенными. Если я напишу,if (myptr == 0)
компилятор сделает правильную вещь, даже если нулевой указатель внутренне представлен как0xabcdef
.0
является константой нулевого указателя, но это не означает, чтоmyptr == 0
проверяет, все ли битыmyptr
равны нулю.NULL
макрос вообще, а говорил о «нулевом указателе» и явно упомянул, что «литерал-0 может быть неявно преобразован в нулевой указатель».Указатель - это просто переменная, которая в основном имеет целочисленный тип. Он указывает адрес памяти, где хранится фактический объект.
Большинство языков позволяют получить доступ к членам объекта через эту переменную указателя:
Компилятор знает, как получить доступ к членам
Apple
. Он «следует» за указателем наmyApple
адрес и извлекает значениеappleInt
Если вы присваиваете нулевой указатель переменной указателя, вы делаете указатель указателем на отсутствие адреса памяти. (Что делает доступ участника невозможным.)
Для каждого указателя вам нужна память для хранения целочисленного значения адреса памяти (в основном 4 байта в 32-битных системах, 8 байтов в 64-битных системах). Это также верно для нулевых указателей.
источник
Быстрый пример (обратите внимание, что имена переменных не сохраняются):
Приветствия.
источник