【问题标题】:Using malloc is giving me more memory than expected?使用 malloc 给了我比预期更多的内存?
【发布时间】:2019-06-04 11:45:35
【问题描述】:

我正在努力掌握malloc,到目前为止,在测试和使用它时,我大多得到了意想不到的结果。

int main(int argc, char** argv)
{
    int size = 10;
    int *A;
    A = (int *)malloc(size * sizeof(int));
    for (int i = 0; i < 10000; i++)
    {
        A[i] = i;
    }
    for (int i = 0; i < 10000; i++)
    {
        printf("%d) %d\n", i, A[i]);
    }
}

以上面的示例代码为例,代码运行时不会出现错误。即使我只分配了A 来保存 10 * int,所以我希望循环在遇到错误之前只运行 10 次。如果我将循环增加到大约 30-40k,则会遇到分段错误。但是,如果我将大小增加到循环量,它总是会像预期的那样工作。所以我知道如何避免错误.. 有点,我只是希望有人能很好地解释为什么会这样。

编辑:原来我不明白 C 没有检测到越界,Java 和 C++ 对我的照顾太多了。我有未定义的行为,现在我知道阻止它们是我的工作。感谢所有回复的人。

【问题讨论】:

  • 不要投malloc()和一般void *,它太冗长,因此不受欢迎
  • 内存缓冲区溢出是未定义的行为,这意味着您不知道会发生什么。 malloc 不必准确地返回您请求的内存量。它返回至少与您请求一样多的内存,或者什么也不返回。
  • 对那些认为这是重复的人感到抱歉。我什至不知道未定义的行为是什么,这就是我的程序正在经历的,所以在创建这样的线程之前很难搜索该术语。相信我,在我在这里问之前,我搜索了很多,并查看了其他 stackoverflow 帖子。无论如何,我很抱歉,感谢所有这么快回复的人,你提供的帮助比你想象的要多:)
  • 绝对没有什么可道歉或感到愚蠢的。你已经学会了 C 和你所来自的语言之间的区别,这很棒
  • 如果这些答案之一对您有帮助,您应该accept it

标签: c arrays memory dynamic malloc


【解决方案1】:

C 不需要对数组访问执行任何边界检查。它可以让你在没有任何警告或错误的情况下读/写过去。

您正在调用undefined behavior 通过读取和写入超过分配内存的末尾。这意味着您的程序的行为无法预测。它可能会崩溃,它可能会输出奇怪的结果,或者它可能(如您的情况)似乎正常工作。

程序会崩溃并不意味着它会崩溃。

【讨论】:

  • 感谢您的回答,我也是 C 语言的新手,而且编程一般。我不知道即使我认为它不应该运行该程序仍会运行。所以基本上只要小心不要超过我分配给它的内存并通过某种检查我应该可以使用它吗?
  • @ChrisRafferty 正确。您需要自己跟踪大小,并确保不做不该做的事情。
  • 这个好答案的一个微妙点:C 不要求边界检查。 C 编译器可以发出代码来对数组访问执行此类检查 - 或不。
【解决方案2】:

未定义的行为并不意味着“保证分段错误”;在某些情况下它可能会起作用。

在你最终崩溃之前,没有办法知道你可以超出数组的边界多远;即使取消引用超出边界的一个元素也是未定义的行为。

另外:如果malloc 成功,它将分配至少与您请求一样多的空间,可能更多。

【讨论】:

  • 感谢您像之前的其他一些用户一样澄清这一点。最重要的是,它至少给了我所要求的那么多,然后我设置了检查以确保它永远不会结束。我只是不明白程序会在超过分配的内容时运行,但现在我知道了,再次感谢。
【解决方案3】:

代码运行没有错误,但仍然是错误的。你只是没有注意到它。您的循环用完了分配的区域,但系统仍然不知道这一事实,直到您用完程序可以访问的更大区域。

这样想象:

<UNAVAILABLE><other data>1234567890<other data><UNAVAILABLE>

您的 10 个 ints 位于其他数据的中间,您可以读取甚至写入这些数据 - 造成非常不愉快的影响。 C 在这里没有牵你的手——只有当你用完可用的总内存时,程序才会崩溃,而不是之前。

【讨论】:

  • 感谢您抽出宝贵时间回复。我实际上并不知道程序可以在不应该运行的时候运行。我只是预料到某种越界错误,然后它就会崩溃。猜猜我学到了一些有价值的东西,再次感谢!
猜你喜欢
  • 2015-08-27
  • 2013-11-14
  • 2011-03-31
  • 1970-01-01
  • 2021-03-26
  • 2019-08-20
  • 1970-01-01
相关资源
最近更新 更多