1

我正在玩 C++ 指针。我为指针分配了内存,但之后我没有释放它。下次我运行程序时,指针驻留在同一个地址上——为什么?操作系统不应该看到该地址被占用从而产生内存泄漏吗?

int* a = new int[1]; //or (int*) malloc(1);
cout << &a << endl; //always 0x28fe98
4

6 回答 6

8

几个误会...

  1. 表达式&a是变量a的地址,即指针的地址,类型为pointer-to-pointer-to-int。本身的值无关紧要a,即不管是否初始化,它的地址都是一样的。你可能想做cout << a << std::endl;

  2. 对于程序的每次运行,操作系统都会分配一个全新的地址空间,并在程序完成时释放它,所以即使你不释放内存,它也会在程序完成时被释放。而且即使程序没有完成,每个进程都有自己的地址空间,所以一个进程分配的内存不会影响另一个进程的内存。

  3. 相同程序的多次运行产生或多或少相同的地址是很自然的,除非使用某种形式的虚拟空间随机化(出于安全目的)。

无论如何,请记住,在 C++ 中基本上有 3 种类型的内存:静态(全局变量)、自动(局部变量)和动态(新对象)。在您的示例中,a(with address &a) 是自动的或静态的,从上下文中不清楚,但a(address a) 指向的整数是动态的。你可能想和他们三个一起玩,看看他们有什么不同。

一个特别有趣的实验是递归函数中局部变量的地址:

void rec(int x)
{
    cout << x << ": " << &x << endl;
    if ( x > 0)
        rec(x - 1);
}
于 2013-05-22T18:20:38.907 回答
6

如果再次运行该程序,则意味着上一次运行结束。这意味着操作系统回收了内存。内存泄漏并不意味着内存永远保留给您的应用程序,即使在它结束之后也是如此。操作系统比这更聪明。

于 2013-05-22T18:17:41.000 回答
1

内存泄漏通常与进程相关联。当进程终止时,它的内存资源被操作系统回收。

也就是说,关于内存泄漏的维基百科文章是这样说的:

可能会发生更严重的泄漏...* 在操作系统上运行时不会在程序终止时自动释放内存。通常在此类机器上,如果内存丢失,只能通过重新启动来回收,AmigaOS 就是此类系统的一个示例。

但是,现代主流操作系统不太可能出现这种现象。

于 2013-05-22T18:35:41.367 回答
0

终止程序将告诉操作系统释放程序分配的所有内存。

显然,它选择了相同的内存地址来分配供您在后续运行中使用。

于 2013-05-22T18:18:05.643 回答
0

您正在打印变量的地址,而新的返回地址..您应该打印

IE

cout << a << endl;

为了更清楚地说明您看到的是编译器生成的偏移量(这是加载进程的偏移量),因此它甚至不依赖于加载进程的位置。进程的起始地址存储在处理器的寄存器中。

我想如果你在它之前添加另一个声明,你会看到一个不同的地址。

int b=0;

int * a = new int[1];

现在您应该在重新编译和运行时看到更改,您应该看到不同的地址。但事实上,无论如何这可能不是故意的。

于 2013-05-22T18:18:36.117 回答
0

如果程序结束,则不再为该程序保留内存。当然,指针并不总是指向那个内存地址,它只是发生在你每次运行它时。如果您打开更多程序然后再次运行它,地址可能会改变。

于 2013-05-22T18:20:24.567 回答