即使没有删除,c ++指针总是在同一个地址上

时间:2013-05-22 18:15:43

标签: c++ pointers memory-management dynamic-memory-allocation

我在玩C ++指针。我将内存分配给指针,但之后我没有释放它。下次运行程序时,指针位于同一地址 - 为什么?操作系统是否应该将该地址视为占用,从而产生内存泄漏?

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

6 个答案:

答案 0 :(得分:8)

一些误解......

  1. 表达式&a是变量a的地址,即指针的地址,指向指针指向int的类型。 a本身的值无关紧要,也就是说,它是否被初始化,它的地址是相同的。您可能想要cout << a << std::endl;

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

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

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

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

    void rec(int x)
    {
        cout << x << ": " << &x << endl;
        if ( x > 0)
            rec(x - 1);
    }
    

答案 1 :(得分:6)

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

答案 2 :(得分:1)

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

那就是说Wikipedia article on Memory Leaks说了这个:

  

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

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

您正在打印变量的地址,而new会返回一个地址..您应该打印

cout << a << endl;

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

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

喜欢

int b=0;

int * a = new int[1];

现在您应该在重新编译和运行时看到更改,您应该看到不同的地址。但事实上,在任何情况下都可能无意。

答案 5 :(得分:0)

如果程序结束,则不再为该程序保留内存。当然,指针并不总是指向那个内存地址,它只是发生在你每次运行它到目前为止。如果再打开一些程序然后重新运行,地址可能会改变。