"... приложение продолжает падать., ... Может кто-нибудь сказать мне, в чем проблема?"
Да, ваша программа пытается записать в область памяти, которой она не принадлежит,
Если вы должны использовать указатель на person
, создайте немного памяти перед его использованием:
int main()
{
person *myPerson = calloc(1, sizeof(*myPerson));
if(!myPerson) return 0; //test if failed
initPerson(myPerson, "Oscar", 45);
printf("%s, %i", myPerson->name, myPerson->age);
free(myPerson);//free memory
return 0;
}
Или вы можете просто передать адрес не-показатель экземпляра person
(с использованием &
) для получения тех же результатов:
int main()
{
person myPerson = {0};
initPerson(&myPerson, "Oscar", 45);
printf("%s, %i", myPerson.name, myPerson.age);
return 0;
}
Оператор:
person *myPerson;
Создает только неинициализированный указатель, не указывающий на какой-либоособое место в памяти во время создания.На этом этапе используется только пробел для самого указателя, sizeof(person *)
.(4 или 8 байтов для 32-битной или 64-битной цели соответственно.) Прежде чем переменная-указатель может быть использована таким образом, пространство должно быть динамически , выделенным путем вызова _ void * calloc (size_t)nitems, size_t size) _ или семейство.Память, созданная таким образом, устанавливает адрес указателя на ячейку памяти, совпадающую с первым байтом непрерывного блока из nitems*size
байтов, выделенных и выделенных для использования с, в данном случае, myPerson
.Память, выделенная таким образом, называется кучей памяти и должна быть явно освобождена с помощью вызова free () , когда она больше не нужна.Как правило, этот метод рекомендуется только в том случае, если требования к памяти для конкретной переменной не известны во время компиляции
Но утверждение:
person myPerson;
Статически (Или автоматически , в зависимости от того, когда и где он создан.) выделяет память с sizeof(person)
байтами для немедленно используемого экземпляра myPerson
, расположенного в памяти по адресу: &myPerson
.Память, созданная таким образом, упоминается как стековая память .Поскольку передача адреса myPerson
(&myPerson
) в качестве аргумента initPerson()
и выполнение того же действия, что и с динамически распределенной памятью (обсуждаемой выше), это гораздо более простой вариант, поскольку он не требует каких-либосоздание или освобождение памяти.
Объяснена память стека и кучи.
Обсуждение автоматического, статического и динамического выделения памяти