【问题标题】:C memory free confusionC 内存释放混乱
【发布时间】:2011-12-27 16:32:19
【问题描述】:

我有一个关于我的代码的简短问题。我创建了两种情况或示例进行测试。

示例 1:

char *arr[1000000];
int i = 0;
for (; i < 1000000; i++){
    char *c = (char *) calloc(1, sizeof(char) * 10);
    free(c);
}

示例 2:

char *arr[1000000];
int i = 0;
for (; i < 1000000; i++){
    char *c = (char *) calloc(1, sizeof(char) * 10);
    arr[i] = c;
    free(arr[i]);
    arr[i] = NULL;
}

示例中的不同之处:在释放内存之前放入数组。

当我运行示例 1 时,它释放了所有内存。当我运行示例 2 时,它不会释放所有内存。 我找了又看,还是没弄明白。

为什么示例 2 的结果与示例 1 不同?

我的常识告诉我示例 1 和示例 2 的结果应该相同,但实际上并非如此。我使用 linux top 来检查内存使用情况。

【问题讨论】:

  • 你怎么知道它不会释放所有内存?
  • 您如何推断第二个示例没有释放所有内存?
  • 你检查了什么?进程的 RSS?
  • 如果你真的认为有些东西被遗漏了,我会在 valgrind 下运行这两个。

标签: c memory free


【解决方案1】:

结果是一样的。我不确定您为什么认为存在差异。

【讨论】:

  • @Tim 你如何检查内存使用情况?
  • 这可能是因为编译器在第一个示例中完全省略了arr(节省了几kb),因为它没有被使用。顺便说一句,在正常情况下,您不会看到内存使用率 decrease with top.
  • @Mat:当我更频繁地运行循环时,内存中的差异变得越来越大
  • @jpalecek:如果是这样,我怎样才能减少内存使用?
  • @TimMeijer:我不敢说我​​真的不相信,或者你看错了专栏,或者测量了其他东西。即使calloc 不只是在每次迭代中分发相同的块,您的进程最多也有 10MB 的动态分配。根本没有理由该进程应该或将在终止之前将其释放回操作系统。
【解决方案2】:

两者都是一样的。

由于您使用top 读取内存,因此可以通过编译器优化来解释差异。例如,示例一中的数组可以完全优化出来。

要检查内存问题,您应该使用 valgrind 或类似的工具。

【讨论】:

    【解决方案3】:

    这是由请求分页引起的。该进程具有数组的地址空间(即:存在它的分页表条目)但没有附加内存(尚未)。循环分配给(最终)属于 array[] 的所有内存页面,因此在循环结束时所有页面都已“故障输入”。

    作为概念证明,您可以将循环替换为:

    for (; i < 1000000; i++){
        arr[i] = "hello, world!";
    }
    

    结果可能(几乎)与 sn-p#2 中的相同

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-30
      • 1970-01-01
      • 2016-01-21
      • 2012-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多