【问题标题】:Arrays of which size require malloc (or global assignment)?什么大小的数组需要 malloc(或全局分配)?
【发布时间】:2011-09-23 08:04:03
【问题描述】:

当我开始使用 C 时,我很快注意到 int array[big number] 在函数内部调用时会导致我的程序崩溃。没那么快,我发现我可以通过定义具有全局范围(在函数之外)的数组或使用 malloc 来防止这种情况发生。

我的问题是:

从多大开始需要使用上述方法之一来确保我的程序不会崩溃?

我的意思是,仅将 int i; 用于计数器和 int chars[256]; 用于小型数组是否安全,或者我应该只对 all 局部变量使用 malloc 吗?

【问题讨论】:

    标签: c malloc


    【解决方案1】:

    您应该了解函数中的int chars[256] 和使用malloc() 之间的区别。

    简而言之,前者将整个数组放在堆栈上。后者分配您从堆中请求的内存。一般来说,堆比栈大很多,但每个的大小都可以调整。

    另一个关键区别是,从技术上讲,从方法返回后,分配在堆栈上的变量将消失。 (哦,如果您继续访问该数组,您的程序可能会像它没有消失一样运行,但是危险潜伏着。)使用 malloc 分配的一大块内存将保持分配状态,直到您明确释放它或程序退出.

    【讨论】:

    • 调整堆栈大小听起来很有趣。这将保证在一定(更重要的是:我知道)数组大小的范围内的稳定性。我该怎么做?
    • 这取决于您的编译器/链接器。你可以谷歌一下。
    • 我是编译语言的新手,所以我没有意识到这是由链接器定义的。 -help 放弃了必要的开关。
    • 通常只有在内存非常紧张的设备上执行嵌入式编程之类的操作时才需要更改堆栈的大小。在这种情况下,您可能会将堆栈大小设置得尽可能低。我会说在大多数情况下,您不会增加堆栈大小,以便您可以将更大的数组分配为局部变量。在这种情况下,您可能需要重新考虑您的设计。 (@K-ballo 在另一条评论中提到了递归,这可能会让你也考虑增加堆栈大小。)
    • 另请注意,如果您在函数中静态声明数组(即 static int bigarray[1000]),它将被放置在堆上而不是堆栈上。这与您的第一个工作解决方案(全局变量)除了范围之外并没有什么不同。
    【解决方案2】:

    您应该使用malloc 进行动态内存分配。对于函数内的静态大小的数组(或任何其他对象),如果所需的内存太大,您将很快遇到分段错误。我不认为可以定义“安全限制”,它可能是特定于实现的,其他因素也在起作用,比如当前堆栈和当前函数的调用者在其中创建的对象。我很想说只要不涉及递归,任何低于页面大小(通常为 4kb)的东西都应该是安全的,但我认为没有这样的保证。

    【讨论】:

      【解决方案3】:

      这取决于。如果您可以保证一行永远不会超过 100 ... 1000 个字符,那么您可以使用固定大小的缓冲区。如果你不这样做:你没有。读取整洁的 x KB 配置文件和 x GB XML 文件(没有 CR/LF)是有区别的。视情况而定。

      下一个选择是:你想让你的程序优雅地死去吗?这只是一种设计选择。

      【讨论】:

      • 这根本不是关于优雅地死去int array[1000000] 导致我的程序崩溃。 int *array = malloc(4000000) 不...
      • @Dennis:这是你的程序。你是(应该是)工程师。一辆汽车的设计速度不是 200 公里/小时,也许计算机程序的设计不是为了处理超过 200 个字符的行长。这是一种设计选择。 OTOH:计算机程序可以选择优雅地死去,汽车制造商只能说:不要那样做。
      • 我们不了解对方。如果没有足够的可用内存,我不想使用 malloc 提供简洁的错误消息而不是简单的崩溃。如果我事先知道堆栈有多大,这两种情况都不会发生。
      • @Dennis:只有知道输入有多大才能保证。具有固定和有限内存需求的程序可以计算其内存需求。 XML 处理的东西、DBMS、编辑器或浏览器都没有。所以它需要一个“或多或少优雅地死去”的策略。
      • @wildplasser:我认为错过的一点是:malloc 通过返回 0 优雅地失败。程序员现在可以做很多事情,包括突然退出,但也可以用较小的请求重试等. 在堆栈上分配一个巨大的数组,导致堆栈溢出(你认为这个站点的名字是从哪里来的!?)进入堆、程序本身或其他一些无效的地方会crash 程序。没有重试,没有用户友好的“太大”错误消息,只是,崩溃。至少在现代操作系统上,它不会把整台机器也搞垮。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 2020-01-28
      • 1970-01-01
      • 1970-01-01
      • 2011-02-28
      • 2012-10-31
      相关资源
      最近更新 更多