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
FPGA 5 Мар 2015 в 17:11

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, который является регистром, в котором хранятся возвращаемые значения функции (для целочисленных типов и типов указателей).

1
eduffy 5 Мар 2015 в 14:28

У вас неопределенное поведение.

Указатель p внутри main() никогда не инициализируется без возврата из функции New_person(). Таким образом, использование неинициализированной переменной приводит к неопределенному поведению.

Вы выделяете некоторую память в куче, а адрес, возвращаемый malloc (), никогда не известен указателю p в main(). Итак, вы обращаетесь к некоторой случайной памяти, и, к вашему счастью, случайная память - это та, которую вы выделили в куче.

4
Gopi 5 Мар 2015 в 14:29