繁体   English   中英

如何为局部变量分配内存?

[英]how is memory allocated for local variables?

int* pi;
{
    int ar[1000000];
    int a =3,b=4;
    ar[3]=a*b
    pi=ar;
}//ar is destroyed
int ar2[]={5,6,7,8,9};
char* f="zcxzsdaaaaaaaaa";
std::cout<<pi[3]<<std::endl;// prints 12

我有两个问题:

  1. 我听说堆栈仅包含指向数据的指针。 如果是这样,数据存储在哪里? 例如char* a="bbbb"; 一个-放在堆栈上,“ bbbb”-其他位置。 哪里?

  2. 上面的代码不能正常工作,意味着内存泄漏为1000000字节吗? 变量ar被销毁,但它指向的数据仍然存在。 而且我们不能在这里使用delete,因为ar不是动态分配的。

我听说堆栈只包含指向数据的指针

你听错了 堆栈包含实际数据。 但是,如果该数据是指针,则存储该数据。

如果是这样,数据存储在哪里? 例如char * a =“ bbbb”; 一个-放在堆栈上,“ bbbb”-其他位置。 哪里?

是的, a (指针)存储在堆栈中。 实际的字符串"bbbb"存储在可执行文件的固定部分中。

上面的代码正常工作是否意味着1000000字节的内存泄漏? 变量ar被销毁,但它指向的数据仍然存在。 而且由于ar不是动态分配的,因此我们不能在这里使用delete。

不,数组和指向数组的指针之间有区别。 ar (整个1000000字节)将存储在堆栈中。 这与char const* ar = "... 1000000 chars ..."; ar在堆栈中时,它将自动“释放”。

char const* a = "abcde"; // a is on the stack, pointing to "abcde" somewhere else.
char const b[6] = "abcde"; // *all* of b is on the stack, all 6 bytes

您的代码中的问题是pi指向堆栈上不再存在的内容。 当您运行代码时,它很可能在那里,因为“释放”堆栈中的数据对非调试版本中的数据没有任何作用。 这不是内存泄漏,您只有一个无效的指针。

最后说明:尽管基本上所有现代计算机体系结构都使用调用堆栈,但是C ++标准没有提及它。 请注意,人们通常会说一个变量在栈上,但实际上可能只是存在于寄存器中。 例如,如果您编译代码,则变量pi可能永远不会接触堆栈,它可能会在函数有效期内一直停留在寄存器中,因为转到堆栈的费用相对较高(与寄存器相比)。

ar也位于“堆栈上”。 从技术上讲,您可以访问它,因为内存仍被映射到地址空间(堆栈通常被映射为一个整体),并且可以看到与先前存储的数据相同的数据,因为数据恰好没有被覆盖

这样做是未定义的行为-您可以读取覆盖的数据,或者程序可能崩溃,或者包括感知到的正常操作在内,可能发生任何其他事情。 不要依靠这种行为,也不要在真实的代码中尝试这种行为(出于教育目的尝试这种行为并询问SO是可以的)。

此处没有内存泄漏-函数退出时,堆栈内存会自动回收。

  1. 你听错了。 堆栈包含数据

  2. 不,整个数组超出范围都可以视为“已销毁”

1)所有变量都在堆栈中。 您不会自己分配内存。

2)没有内存泄漏。 整个变量在堆栈上,并且在退出变量范围时被破坏。 您不会使用new分配任何内容。

似乎并没有真正解决内存泄漏的混乱。 在C ++中,您可以使用new关键字或malloc自己分配内存,这是内存泄漏值得关注的时候。 设计语言时,一旦超出范围,将回收所有局部变量存储空间。 每个人都指出ar位于pi {}的本地范围内,因此一旦退出,这些内存位置就可以重用或轻易覆盖,因此,如果您稍后将在代码中打印pi的结果并像您一样操作堆栈, {}范围与pi可能是不同的值

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM