【问题标题】:Memory leaks: When do they happen? [closed]内存泄漏:它们何时发生? [关闭]
【发布时间】:2011-03-23 10:01:39
【问题描述】:

我有 8GB 的​​内存和 80GB 的硬盘。 我有如下所示的三个程序。

1)

main()
{

  while(1)
     x();
}

x()
{
  printf("hello\n");
}

上面的程序这里会不会有内存泄漏?我想不会。如果它没有发生,那么会发生什么?什么时候停止?

2)

main()
{
   int *x;
   while(1)
      x=malloc(100*size(int));//there is a memory leak here
}

很明显这个程序会在一段时间后崩溃,但我想知道何时,查看我上面提到的资源。

3)

main()
{
   x();
}
x()
{
   x();
}

上面的程序是无限递归的吗?最终会发生什么?考虑到我拥有的资源,这个程序什么时候会崩溃/死机?

【问题讨论】:

  • 我有一个问题要问你。当您尝试这些程序时会发生什么?需要多长时间?
  • 这是三个不同的(相关问题),其中一些无法回答(特别是 2 取决于您的配置、操作系统位数,甚至编译器选项)。更重要的是,答案实际上几乎没有价值......
  • 代码在没有适当缩进的情况下接近“难以阅读”。
  • 我建议你发表你自己的理论来回答,然后我们有一些基础可以帮助你。目前我不清楚你不明白什么。
  • 为什么关闭?为什么这不是一个真正的问题?我只是想知道程序什么时候会崩溃,实际上它可能需要很多时间,有时永远无法找到它什​​么时候会崩溃?

标签: c++ c


【解决方案1】:

第一个程序没有内存泄漏,它将永远运行(或直到它被外部杀死),并愉快地打印该字符串。

第二个内存泄漏,但不会崩溃。您将开始从malloc 获取NULL。否则,效果与上面的数字 1 相同。

第三个最终会溢出堆栈,除非您在编译器中有一些特别好的尾端递归优化,在这种情况下它也将永远运行。

顺便说一句,那段代码特别糟糕。很长一段时间以来,默认返回类型和没有两个规范参数列表的 main 函数是可以接受的。

【讨论】:

  • 你提到的这一点很有意思!“第二个有内存泄漏但不会崩溃”。是真的吗?第二个程序永远不会崩溃吗?
  • +1 获得唯一完全正确的答案
  • @zombie,没错,它不会崩溃。所有这一切都会发生,您将耗尽堆并开始返回 NULL。现在,如果你要尝试使用那段记忆,那就另当别论了。
【解决方案2】:

当您使用malloc() 请求内存而不使用free() 内存时,会发生内存泄漏。

不好的例子

#include <stdlib.h>

int main(int argc, char *argv[]) {
    int *nums = malloc(10 * sizeof(int)); // create array with memory for 10 nums
    nums[0] = 2;
    nums[4] = 8;

    return 0; // main() ended but nums wasn't free'd. Memory leak/
}

好例子

#include <stdlib.h>

int main(int argc, char *argv[]) {
    int *nums = malloc(10 * sizeof(int)); // create array with memory for 10 nums
    nums[0] = 2;
    nums[4] = 8;

    free(nums); // free memory allocated for nums

    return 0;
}

现在关于你的程序。

1 - 重新格式化

这个程序将永远不会结束并永远调用 x(并因此打印 Hello World! 直到时间结束)

#include <stdio.h>

void x(void) {
    printf("Hello World!\n");
}

int main(int argc, char *argv[]) {
    while (1) x();
    return 0;
}

2 - 重新格式化

该程序为每个循环分配 100 个整数的内存,但从不释放此内存。巨大的内存泄漏一直持续到操作系统内存不足。

#include <stdlib.h>

int main(int argc, char *argv[]) {
    int *x;
    while (1) {
        x = malloc(100 * size(int)); // allocate memory for an array of 100 integers
    }

    return 0;
}

3 - 重新格式化

这个程序一直递归直到堆栈耗尽(堆栈跟踪)并且程序将崩溃(堆栈溢出)。

void x(void) {
    x();
}

int main(int argc, char *argv[]) {
    x();

    return 0;
}

【讨论】:

  • 其实你的坏例子并没有那么糟糕。当程序结束时,这些字节将被释放,无论程序是否明确释放它们。内存泄漏只是程序继续运行时的问题。当它终止时,操作系统会回收所有分配给它的内存。
  • @aroth:取决于操作系统,C 标准不保证。
  • C 标准说什么并不重要(并且 C 标准不应该保证操作系统在程序终止时所做的任何事情)。操作系统处理可执行代码,并且无法知道程序 X 是用 C 编写的。如果操作系统在程序终止后留下任何驻留在内存中的内容,那么这就是操作系统中的错误,与任何事情无关程序做了或没有做。
  • "操作系统处理可执行代码,无法知道程序 X 是用 C 编写的。" C 语言也是如此:程序员处理 C 代码,并且无法知道 OS Y(X 太混乱)是否清理了他的混乱。
  • 如果这个程序被编译为 32 位程序,它很可能会在操作系统内存耗尽之前很久就耗尽地址空间。
【解决方案3】:
  1. 没有内存泄漏。该计划永远不会停止。
  2. 这是内存泄漏。因为在程序工作期间您正在分配内存,但在下一步之后您没有任何指向该内存的指针要删除。当内存完成时,这将抛出“bad alloc”错误。
  3. 这里没有内存泄漏,但是当栈内存用完时程序会崩溃。

【讨论】:

  • 这就是我的问题!!!我有一个 8GB 的​​内存!!什么时候会崩溃?
  • 而恰恰相反,OP正在怀疑。 2) 不会崩溃
  • @zombie 3) 取决于堆栈的大小。内存大小无关紧要。
  • @zombie 您可以通过 #pragma comment(linker, "/STACK:size") 配置堆栈内存,其中 size 是以字节为单位的堆栈大小。
  • malloc() 失败时不会抛出,会返回NULL
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-08
  • 1970-01-01
  • 2011-06-28
  • 2013-03-29
  • 2010-11-28
  • 2018-08-26
相关资源
最近更新 更多