简体   繁体   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

I have 2 questions: 我有两个问题:

  1. I heard that the stack contains only pointers to data. 我听说堆栈仅包含指向数据的指针。 And if so where is the data stored? 如果是这样,数据存储在哪里? For example char* a="bbbb"; 例如char* a="bbbb"; a - placed on stack, "bbbb" - somewhere else. 一个-放在堆栈上,“ bbbb”-其他位置。 Where? 哪里?

  2. Doesn't the above code working correctly mean a memory leak of 1000000 bytes? 上面的代码不能正常工作,意味着内存泄漏为1000000字节吗? Variable ar is destroyed but the data that it pointed to still exists. 变量ar被销毁,但它指向的数据仍然存在。 And we can't use delete here since ar is not dynamically allocated. 而且我们不能在这里使用delete,因为ar不是动态分配的。

I heard that stack contain only pointers to data 我听说堆栈只包含指向数据的指针

You heard wrong. 你听错了 The stack contains the actual data. 堆栈包含实际数据。 However, if that data is a pointer then that is what is stored. 但是,如果该数据是指针,则存储该数据。

And if so where is data stored? 如果是这样,数据存储在哪里? For example char* a="bbbb"; 例如char * a =“ bbbb”; a - placed on stack, "bbbb" - somewhere else. 一个-放在堆栈上,“ bbbb”-其他位置。 Where? 哪里?

Yes, a (the pointer) is stored on the stack. 是的, a (指针)存储在堆栈中。 The actual string "bbbb" is stored in a fixed part of the executable. 实际的字符串"bbbb"存储在可执行文件的固定部分中。

Doesnt code above working correctly mean memory leak of 1000000 bytes? 上面的代码正常工作是否意味着1000000字节的内存泄漏? Variable ar is destroyed but data that it pointed to still exists. 变量ar被销毁,但它指向的数据仍然存在。 And we cant use delete here since ar is not dynamically allocated. 而且由于ar不是动态分配的,因此我们不能在这里使用delete。

No, there is a difference between arrays and pointers to arrays. 不,数组和指向数组的指针之间有区别。 ar (the whole 1000000 bytes) will be stored on the stack. ar (整个1000000字节)将存储在堆栈中。 This is different from char const* ar = "... 1000000 chars ..."; 这与char const* ar = "... 1000000 chars ..."; . As ar is on the stack, it will be "freed" automatically. 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

The problem in your code is that pi is pointing to something on the stack which is no longer there. 您的代码中的问题是pi指向堆栈上不再存在的内容。 It may well be there when you run the code because "freeing" data on the stack doesn't do anything to the data in non-debug builds. 当您运行代码时,它很可能在那里,因为“释放”堆栈中的数据对非调试版本中的数据没有任何作用。 It's not a memory leak, you just have an invalid pointer. 这不是内存泄漏,您只有一个无效的指针。

Final note: Although essentially all modern computer architectures make use of a call stack, the C++ standard makes no mention of it. 最后说明:尽管基本上所有现代计算机体系结构都使用调用堆栈,但是C ++标准没有提及它。 Note that people will often say that a variable is "on the stack", but it may actually just live in a register. 请注意,人们通常会说一个变量在栈上,但实际上可能只是存在于寄存器中。 For example, if you compiled your code, the variable pi probably wouldn't ever touch the stack, it would likely just stay in a register for the duration of the function because going to the stack is relatively expensive (compared to registers). 例如,如果您编译代码,则变量pi可能永远不会接触堆栈,它可能会在函数有效期内一直停留在寄存器中,因为转到堆栈的费用相对较高(与寄存器相比)。

ar is also located "on stack". ar也位于“堆栈上”。 You technically can access it because the memory is still mapped into address space (stack is usually mapped as a whole) and see the same data as previously stored because data happens to not have been overwritten . 从技术上讲,您可以访问它,因为内存仍被映射到地址空间(堆栈通常被映射为一个整体),并且可以看到与先前存储的数据相同的数据,因为数据恰好没有被覆盖

Doing so is undefined behavior - you can read overwritten data or your program may crash or anything else may happen including perceived normal operation. 这样做是未定义的行为-您可以读取覆盖的数据,或者程序可能崩溃,或者包括感知到的正常操作在内,可能发生任何其他事情。 Don't rely on this behavior and don't try this in real code (trying this for educational purposes and asking on SO is okay). 不要依靠这种行为,也不要在真实的代码中尝试这种行为(出于教育目的尝试这种行为并询问SO是可以的)。

There's no memory leak here - stack memory is automatically reclaimed when the function exits. 此处没有内存泄漏-函数退出时,堆栈内存会自动回收。

  1. you heard wrong. 你听错了。 the stack contains the data 堆栈包含数据

  2. no, the whole array can be considered "destroyed" when it gets out of scope 不,整个数组超出范围都可以视为“已销毁”

1) All variables are on the stack. 1)所有变量都在堆栈中。 You don't allocate memory yourself. 您不会自己分配内存。

2) There is no memory leak. 2)没有内存泄漏。 The whole variable is on the stack and is destroyed when the scope of the variable is exited. 整个变量在堆栈上,并且在退出变量范围时被破坏。 You're not allocating anything with new . 您不会使用new分配任何内容。

It doesnt seem the confusion of memory leakage is really addressed. 似乎并没有真正解决内存泄漏的混乱。 In C++ to allocate memory yourself you use the new keyword or malloc and this is when memory leakage is a concern. 在C ++中,您可以使用new关键字或malloc自己分配内存,这是内存泄漏值得关注的时候。 The lanaguage is designed that all local variables memory space are reclaimed once it becomes out of scope. 设计语言时,一旦超出范围,将回收所有局部变量存储空间。 As everyone pointed the ar is in the local scope of pi{} so once that is exited, those memory locations could be reused or easily overwritten,so if you would have printed the results of pi later in the code with manipulating the stack like you were in that {} scope than pi could be a different value 每个人都指出ar位于pi {}的本地范围内,因此一旦退出,这些内存位置就可以重用或轻易覆盖,因此,如果您稍后将在代码中打印pi的结果并像您一样操作堆栈, {}范围与pi可能是不同的值

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

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