Неявное выделение памяти и инициализация при объявлении указателя

Возможный дубликат:
Объявление указателя на структуру в C ++ автоматически выделяет память для его членов. Я ошибся?

Скажите, если я определю структуру Human как:

struct Human{int year, Human* Mom};

делает выражение

Human* Bob;

автоматически распределять память как для Боба, так и для Человека, на который он указывает?
Потому что я заметил, что

Bob == NULL

ложно;
Значит ли это, что приведенное выше выражение создает статическую память об объекте Human?

Также я заметил, что

Bob->year

НЕ инициализируется в 0 автоматически, но

Bob->Mom

инициализируется в NULL, почему это так?

Еще одна вещь, если я выделю память динамически, например,

Human* Bob = new Human;

Тогда я обнаружил, что

Bob->Mom

больше не NULL, как это происходит?

-2

Решение

Как минимум, объявление структуры должно быть исправлено следующим образом:

struct Human { int year; Human *Mom; };

Заявление:

Human *Bob;

затем создает хранилище, но не инициализирует его, если оно создано внутри функции. Если он находится в глобальной области видимости, он будет инициализирован нулем (NULL), но вы говорите Bob == NULL имеет значение false, поэтому это должна быть неинициализированная локальная переменная. Это ни на что не указывает. Любое его использование, кроме как в качестве цели для назначения, вызывает неопределенное поведение, потому что значение в Bob не определено

Нет; показанное определение не выделяет память для Bob указать на.

Все остальные ваши наблюдения зависят от особенностей вашей системы исполнения. Поскольку поведение не определено, может произойти все что угодно, и все в порядке в соответствии со стандартом. Вам нужен конструктор по умолчанию для типа, чтобы получить значения, разумно установленные при использовании:

Human *Bob = new Human;

Вы не предоставили один, и система не должна предоставлять его, поэтому объект, на который указывает, неинициализирован.

1

Другие решения

Нет, это не выделяет память. Боб — это указатель со значением мусора, поэтому кто знает, на что он указывает.

0

делает выражение Human * Bob; автоматически выделить память для объекта Боба и человека, на который он указывает? Потому что я заметил, что Боб == NULL является ложным; Значит ли это, что приведенное выше выражение создает статическую память об объекте Human?

Нет, это не так. Боб не инициализирован, поэтому просто укажет на случайный мусор. Вы должны явно выделить память для Боба.

Другое дело, если я выделяю память динамически, например, Человек * Боб = новый Человек; Потом я обнаружил, что Bob-> Mom больше не NULL, как это происходит?

Как и выше, в неинициализированной памяти может быть что угодно. Попытка следовать указателю приведет к катастрофе. Хорошей практикой является инициализация всех указателей на NULL или немедленно направить их на выделенный блок памяти.

0

В вашем коде единственная инструкция, которую вы дали компилятору, — создать указатель (32-битная или 64-битная переменная), который вы намереваетесь указать на структуру типа «Human».

Поскольку вы не инициализировали указатель, его значение, скорее всего, соответствует тому, что было в этом пространстве памяти — это может быть 0 (NULL) или что-то еще.

Когда вы вызываете Bob-> Mom, вы разыменовываете указатель (Bob) и просматриваете произвольную область в памяти (потенциально пространство, к которому у вас нет доступа). Скорее всего, вы получите ошибку сегментации (на машине * nix).

Что вы должны сделать, это:

Human* Bob = new Human();

Это создаст выделенное пространство для структуры, вернет адрес этой структуры и назначит его указателю Бобу. Теперь, когда вы разыменовываете Боба, он фактически указывает на пространство, которое было выделено специально для структуры Человека.

0

Это ваша ответственность инициализировать значения указателя. Если вы не настроили их на что-то 0 или же NULL), их значение не определено, и вы можете получить разные значения неинициализированного указателя при каждом соответствующем выделении.

С точки зрения распределения, вы определили рекурсивную или самоссылочную структуру данных. Подумайте, что произойдет, если он фактически выделит память для дополнительного Человека для Mom член; Затем он должен был бы выделить другого человека для Bob->Mom->Mom и так далее…

Так что нет. Только один Human выделено. Любой родной указатель — это просто адрес в памяти, не более того.

Вы можете упростить инициализацию указателя, если используете конструктор:

struct Human {
int year;
Human *Mom;
Human() : year(0), Mom(NULL) {}
};
0