【问题标题】:Supposed to return a pointer but compiles fine应该返回一个指针但编译得很好
【发布时间】:2015-03-05 14:11:35
【问题描述】:
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 就像一个构造函数,它应该返回一个指向新分配的人的指针,如果我在 New_Person 函数中注释 return 语句,我仍然会得到相同的行为,有人可以解释一下为什么在没有返回语句的情况下编译并给出相同的行为?

【问题讨论】:

  • 您很幸运,因为您的代码中存在未定义的行为,从而获得了预期的输出。我怀疑编译器是如何没有发出警告说你没有从函数中返回的……
  • @Gopi 我真的不明白我不小心忘记了 return 声明,它仍然有效
  • 寻找“未定义的行为”。这意味着,任何事情都可能发生,编译器不需要告诉你。使用不返回的函数的返回值是未定义的。使用适当的警告设置会捕获一些实例(例如,-Wall 在此处使用 gcc)。
  • @mafso 感谢 -Wall 现在我收到警告

标签: c gcc c99


【解决方案1】:

你所拥有的是未定义的行为。

main() 中的指针p 在没有从函数New_person() 返回的情况下永远不会被初始化。所以使用未初始化的变量会导致未定义的行为。

您在堆上分配了一些内存,而 malloc() 返回的地址对于 p 内的指针 p 永远不知道 main()。因此,您正在访问一些随机内存,幸运的是,随机内存是您在堆上分配的内存。

【讨论】:

    【解决方案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 寄存器中,该寄存器恰好是存储函数返回值的寄存器(对于整数和指针类型)。

    【讨论】:

      猜你喜欢
      • 2020-12-09
      • 2021-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-21
      • 1970-01-01
      • 1970-01-01
      • 2013-10-28
      相关资源
      最近更新 更多