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

时间:2011-12-23 09:14:57

标签: c++ c memory-leaks memory-management

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"; a - 放在堆栈上,“bbbb” - 放在其他地方。在哪里?

  2. 上述代码是否正常工作意味着内存泄漏为1000000字节?变量ar被销毁,但它指向的数据仍然存在。我们不能在此处使用删除,因为ar未动态分配。

5 个答案:

答案 0 :(得分:4)

  

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

你听错了。堆栈包含实际数据。但是,如果该数据是指针,那么就是存储的内容。

  

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

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

  

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

不,数组和指向数组的指针之间存在差异。 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可能永远不会触及堆栈,它可能只是在函数持续时间内保留在寄存器中,因为进入堆栈相对昂贵(与寄存器)。

答案 1 :(得分:3)

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

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

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

似乎没有真正解决内存泄漏的混乱问题。在C ++中自己分配内存,你可以使用 new 关键字或 malloc ,这就是内存泄漏问题。设计lanaguage,一旦它超出范围,所有局部变量的内存空间都会被回收。由于每个人都指出ar位于pi {}的本地范围内,所以一旦退出,这些内存位置可以重复使用或轻松覆盖,所以如果你以后在代码中打印了pi的结果,就像你一样操纵堆栈在{}范围内,pi可能是一个不同的值