指针或值在我的例子中

Pointer or Value in my case?

本文关键字:我的 指针      更新时间:2023-10-16
bool example1()
{
    long a;
    a = 0;
    cout << a;
    a = 1;
    cout << a;
    a = 2;
    cout << a;
    //and again...again until
    a = 1000000;
    cout << a+1;
    return true;
}
bool example2()
{
    long* a = new long;//sorry for the misstake
    *a = 0;
    cout << *a;
    *a = 1;
    cout << *a;
    *a = 2;
    cout << *a;
    //and again...again until
    *a = 1000000;
    cout << *a + 1;
    return true;
}

注意,我没有在example2()中删除a,只删除了一个新手的问题:
1. 当两个函数执行时,哪一个使用更多的内存?
2. 函数返回后,哪一个使整个程序使用更多的内存?
谢谢你的帮助!

update:将long* a;替换为long* a = new long;
更新2:为了避免我们没有对a做任何事情的情况,我每次都计算值

原答案

这要看情况,同时也不会有什么差别。

第一个程序将消耗堆栈上的sizeof(long)字节,第二个程序将消耗sizeof(long*)字节。通常long*至少和long一样大,因此您可以说第二个程序可能使用更多的内存(取决于编译器和体系结构)。

另一方面,堆栈内存是按照操作系统内存页粒度分配的(4KB是一个很好的估计),因此两个程序几乎可以保证为堆栈使用相同数量的内存页。在这个意义上,从观察系统的人的角度来看,内存使用将是相同的。

但是它变得更好:编译器可以自由地决定(取决于设置)你没有对这些局部变量做任何事情,所以它可能决定在这两种情况下根本不分配任何内存。

最后你必须回答"指针指向什么"的问题(正如其他人所说,程序当前编写的方式几乎肯定会由于访问无效内存而崩溃)。

假设它没有(让我们说指针被初始化为一个有效的内存地址),你会计算内存被"使用"吗?

Update (long* a = new long edit):

现在我们知道指针是有效的,堆内存将被分配给long(但没有释放!)堆栈分配和以前一样,但是现在example2也会在堆上使用至少sizeof(long)字节(很可能它会使用更多,但你不能告诉多少,因为这取决于正在使用的堆分配器,而堆分配器又取决于编译器的设置等)。

现在,从观察系统的人的角度来看,这两个程序仍然不太可能显示出不同的内存占用(因为堆分配器很可能会从它已经从操作系统接收到的页面的内存中满足example2中的new long的请求),但是进程的地址空间中肯定会有更少的可用空闲内存。所以在这个意义上,example2将使用更多的内存。多出多少?这取决于分配的开销,如前所述,这是未知的。

最后,由于example2在退出之前不释放堆内存(即存在内存泄漏),即使在返回后它也会继续使用堆内存,而example1则不会。

只有一种方法可以知道,那就是通过测量。由于您从未实际使用您所分配的任何值,编译器可以根据"as-if规则"简单地优化两个函数,直到:

bool example1()
{
    return true;
}
bool example2()
{
    return true;
}

在c++规则下,这将是对你的代码的完全有效的解释。这取决于你来编译和测量它,看看实际发生了什么。


唉,对这个问题的修改使上面的内容有所不同。主要观点仍然成立:除非你测量它,否则你无法知道。现在这两个函数都可以优化为:

bool example1()
{
    cout << 0;
    cout << 1;
    cout << 2;
    //and again...again until
    cout << 1000001;
    return true;
}
bool example2()
{
    cout << 0;
    cout << 1;
    cout << 2;
    //and again...again until
    cout << 1000001;
    return true;
}

example2()从不为指针a引用的值分配内存。如果这样做,它将占用更多的内存,因为它需要long所需的空间以及指向它的指针的空间。

同样,无论你给a赋多少次值,都不会使用更多的内存。

例2有一个不为指针分配内存的问题。指针a最初有一个未知的值,这使得它指向内存中某处的。给这个指针赋值会破坏中某个的内容。

两个示例使用相同数量的内存量。(即4个字节)