0

前段时间我问自己,当我写这样的东西时:

   char* first(int howMany){
      return (char*)malloc(howMany);
   } 

   int main(){
      char*t;
      int one=20;
      t=first(20);  
   }

此代码在codepad.org崩溃,但在 Mepis Linux 11.04 中它只会引发一些警告。

但是如果我为 C++ 写这样的东西:

char* first(int howMany){
    return new char [howMany];
   }

int main(){
    char*t;
    int one=20;
    t=first(20);  
}

此代码工作正常。

我的问题是:

为什么 C 代码不起作用以及发生了什么,当我尝试

return (char*)malloc(howMany)?

PS:如果我尝试在 Objective-C 中使用这个函数会发生什么?

(NSArray*) first(){
    return [NSArray array];
}
4

2 回答 2

8

我在 codepad.org中没有崩溃,它运行,但程序的退出状态指示错误。退出状态是未定义的,只是碰巧在堆栈上,退出值(它恰好是 codepad.org 上的 120)来自您的程序没有从 main() 正确返回任何东西,就像它应该做的那样.

传统上,在 C 和 C++ 中,您必须从 main()显式返回一些内容。在后来的 C 和 C++ 标准中,这发生了变化,因此如果您在没有 return 语句的情况下退出 main(),它将自动返回 0。(0 表示成功。)

似乎发生的事情是你有一个尊重这个标准的 C++ 编译器,(标准 C++ 有这个规则比标准 C 更长的时间),如果 main() 没有返回任何东西,它默认返回 0。

相比之下,codepad.org上的 C 编译器似乎遵循较旧的标准,其中 main() 必须具有显式的 return 语句才能使程序有效。因此,有人可能会争辩说您的程序失败是因为codepad.org没有最新的 C 编译器,或者有人可能会争辩说您的程序应该更加保守,而不是假设现代编译器,而是从 main() 显式返回。

这就是 Mepis Linux 上的编译器向您发出警告的原因。它可能未配置为遵循最新标准,因此警告您应该使用return语句结束 main() 函数。

因此,如果您想编写适用于任何地方的保守代码,您的 main() 函数应始终return语句结尾。您的问题证明,如果您希望您的代码在“现实世界”中工作,依赖新标准的功能可能是危险的。

更改为 Objective C 可能会改变其他内容,但主要问题(双关语)仍然是您没有显式地从 main() 返回值以及 Objective C 的 C 部分在特定编译器中遵循的标准。

您没有释放内存,很可能会导致内存泄漏,但不是程序本身的错误,也不会影响您观察到的问题。(确实,在 Linux 上,退出程序会自动释放所有内存,这可能是一种草率的编程,但并非不正确。)

于 2012-06-14T09:23:51.520 回答
3

在这种情况下C和之间的一个重要区别是,在 中,如果没有显式返回,则函数返回。您的代码示例就是这种情况,因此无论任何代码错误如何,它都被视为在 C++ 中成功退出。C++C++main0

于 2012-06-14T09:41:04.477 回答