typedef struct person {
int id;
char* name;
} Person;
//constructor like function
Person* New_Person(int id,char *name){
Person* p = malloc(sizeof(Person));
p->id = id;
p->name = name;
//return p;
}
int main(){
for(int i=0;i<10;i++){
Person* p = New_Person(i,"abcd");
printf("id:%d name:%s \n",p->id,p->name);
}
printf("DONE\n");
return 0;
}
New_Person
похож на конструктор, и он должен возвращать указатель на только что назначенного человека. Если я прокомментирую оператор return в функции New_Person
, я все равно получу такое же поведение, может кто-нибудь объяснить мне, почему он компилируется и дает такое же поведение без оператора возврата?
2 ответа
У меня такое же поведение, поэтому я разобрал ваш конструктор:
0000000000000000 <New_Person>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 20 sub $0x20,%rsp
8: 89 7d ec mov %edi,-0x14(%rbp)
b: 48 89 75 e0 mov %rsi,-0x20(%rbp)
f: bf 10 00 00 00 mov $0x10,%edi
14: e8 00 00 00 00 callq 19 <New_Person+0x19>
19: 48 89 45 f8 mov %rax,-0x8(%rbp)
1d: 48 8b 45 f8 mov -0x8(%rbp),%rax
21: 8b 55 ec mov -0x14(%rbp),%edx
24: 89 10 mov %edx,(%rax)
26: 48 8b 45 f8 mov -0x8(%rbp),%rax
2a: 48 8b 55 e0 mov -0x20(%rbp),%rdx
2e: 48 89 50 08 mov %rdx,0x8(%rax)
32: c9 leaveq
33: c3 retq
Похоже, ваш указатель хранится в регистре rax
, который является регистром, в котором хранятся возвращаемые значения функции (для целочисленных типов и типов указателей).
У вас неопределенное поведение.
Указатель p
внутри main()
никогда не инициализируется без возврата из функции New_person()
. Таким образом, использование неинициализированной переменной приводит к неопределенному поведению.
Вы выделяете некоторую память в куче, а адрес, возвращаемый malloc (), никогда не известен указателю p
в main()
. Итак, вы обращаетесь к некоторой случайной памяти, и, к вашему счастью, случайная память - это та, которую вы выделили в куче.
Похожие вопросы
Связанные вопросы
Новые вопросы
c
C - это язык программирования общего назначения, используемый для системного программирования (ОС и встраиваемых), библиотек, игр и кроссплатформенности. Этот тег следует использовать с общими вопросами, касающимися языка C, как это определено в стандарте ISO 9899 (последняя версия 9899: 2018, если не указано иное, а также для запросов, специфичных для версии, с c89, c99, c11 и т. Д.). C отличается от C ++ и не должен сочетаться с тэгом C ++ без разумной причины.