我是C ++的新手,所以请原谅我的无知。我的印象是, {
和}
之间的任何内容都称为范围,并且您可以通过添加函数或其他任何内容创建单独的范围更多括号。例如:
int foo(){
std::cout << "I'm inside the scope of foo" << std::endl;
{
std::cout << "I'm inside a scope that's inside the scope of foo" << std::endl;
}
}
关于指针和内存泄漏,我正在学习这一点。我的理解是,当您离开范围时,所有变量都应从内存中释放出来,除非内存是用 new
或 malloc
手动分配的。但是,在我的测试中,情况似乎并非如此。我已经编写了以下脚本来测试以下内容:
#include <iostream>
void test(){
{
int regdata = 240;
int* pointerInt = new int(1);
*pointerInt = 15;
std::cout << "RegData Addr: " << ®data << std::endl;
std::cout << "Value: " << regdata << std::endl;
std::cout << "Pointer Addr: " << &pointerInt << std::endl;
std::cout << "Pointer: " << pointerInt << std::endl;
std::cout << "Value: " << *pointerInt << std::endl;
std::cout << std::endl;
std::cout << "Press any key then enter to leave the scope.";
char temp;
std::cin >> temp;
//delete pointerInt;
}
std::cout << "The scope has been left." << std::endl;
std::cout << "Press any key then enter to leave the function.";
char temp;
std::cin >> temp;
}
int main(){
test();
std::cout << "The function has been left." << std::endl;
std::cout << "Press any key then enter to leave the program.";
char temp;
std::cin >> temp;
}
我在Windows 10计算机上启动此程序,并一直使用程序作弊引擎监视内存使用量。现在,取决于我是否有 delete
评论说,它将删除容纳 15
的字节,并在我离开范围时用随机字节替换它们。但是,持有 240
的内存直到我离开 test
的范围之后才释放(在这一点上, 240
被替换为 > 1
)。而且,无论是否发表 delete
,实际的指针本身都不会从内存中删除。
我的编译器还是我的机器无法正确编译/运行我的代码?还是我误解了范围之间的内存管理?如果是后者,请纠正我,以便我可以正确理解应该发生的事情。另外,让我知道是否有意义!
I'm fairly new to C++ so please forgive me for my ignorance. I'm under the impression that anything between {
and }
is called a scope, and that you can create a separate scope inside a function, or anything else, just by adding more brackets. For example:
int foo(){
std::cout << "I'm inside the scope of foo" << std::endl;
{
std::cout << "I'm inside a scope that's inside the scope of foo" << std::endl;
}
}
I was learning about this in relation to pointers and memory leaks. My understanding is when you leave a scope all variables should be freed from memory unless the memory was manually allocated with new
or malloc
. In my testing, however, this does not seem to be the case. I've written the following script to test this:
#include <iostream>
void test(){
{
int regdata = 240;
int* pointerInt = new int(1);
*pointerInt = 15;
std::cout << "RegData Addr: " << ®data << std::endl;
std::cout << "Value: " << regdata << std::endl;
std::cout << "Pointer Addr: " << &pointerInt << std::endl;
std::cout << "Pointer: " << pointerInt << std::endl;
std::cout << "Value: " << *pointerInt << std::endl;
std::cout << std::endl;
std::cout << "Press any key then enter to leave the scope.";
char temp;
std::cin >> temp;
//delete pointerInt;
}
std::cout << "The scope has been left." << std::endl;
std::cout << "Press any key then enter to leave the function.";
char temp;
std::cin >> temp;
}
int main(){
test();
std::cout << "The function has been left." << std::endl;
std::cout << "Press any key then enter to leave the program.";
char temp;
std::cin >> temp;
}
I start this program on my Windows 10 computer and have been monitoring the memory usage using the program Cheat Engine. Now, depending on whether or not I have delete
commented out it will delete the bytes that hold 15
and replace them with random bytes when I leave the scope as it should. However, the memory holding the 240
is not freed until after I leave the scope of test
(at which point the 240
is replaced with 1
). And regardless of if the delete
is commented out, the actual pointer itself is never deleted out of memory.
Is my compiler or my machine not compiling/running my code correctly? Or am I misunderstanding memory management between scopes? If it's the latter, please correct me so I can properly understand what is supposed to happen. Also let me know if something doesn't make sense!
发布评论
评论(2)
离开范围时,记忆不会“释放”。在该范围内声明的所有具有自动存储持续时间的变量的寿命。当变量的寿命结束时会发生什么?对于
int
或指针之类的简单值:可能绝对没有。该变量的寿命已经结束,因此尝试使用它会导致不确定的行为,但通常不会立即发生该值。编译器知道,现在可以重复使用该变量的存储空间,但是直到它实际重复使用它,旧值可能会继续存在。编译器可以立即将其生命已经结束的变量的记忆归零,并且对于调试构建也许会这样,但是这样做会花费时间,因此大多数编译器都不会打扰。Memory is not "freed" when you leave a scope. The lifetime of all variables with automatic storage duration that were declared within that scope end. What happens when the lifetime of a variable ends? For simple values like an
int
or a pointer: likely absolutely nothing. The lifetime of the variable has ended, so attempting to use it results in undefined behavior, but usually nothing will immediately happen to the value. The compiler knows that the storage in which the variable resided is now available to be re-used, but until it actually re-uses it the old value will likely continue to exist. A compiler could immediately zero out the memory of variables whose lifetime has ended, and for a debug build maybe it will, but doing so would take time so most compilers won't bother.regdata
存储在堆栈上,因此它使用的内存通常永远不会被“释放”,直到代码正在运行的线程结束。发生的事情是堆栈内存现在可以再次使用用于其他东西。您访问
std :: Cout
和std :: cin
都需要使用一定数量的堆栈内存,如果他们使用足够的内存内部范围中的值(根据编译器的实现,无法保证它会在函数稍后重复使用内部范围堆栈内存,它可能会决定使用更多堆栈内存更快)。这就是为什么
regdata
始终被1
覆盖,这是稍后堆栈使用情况的巧合,而不是编译器故意的操作。一些编译器在发布后可能会故意覆盖堆栈记忆以帮助调试,但在正常发布的构建中,这将是不必要的浪费时间。regdata
is stored on the stack so the memory it uses will never normally be "freed" until the end of the thread that the code is running in.What does happen is that the stack memory is now available again to be used for something else. Your calls to
std::cout
andstd::cin
will both need to use a certain amount of stack memory, if they use enough memory then they'll overwrite all of the values in your inner scope (depending on the implementation of your compiler, there's no guarantee that it'll reuse the inner scopes stack memory later in the function, it might decide it's faster to use more stack memory instead).This is why
regdata
is always being overwritten with1
, it's a coincidence of later stack usage rather than a deliberate action by the compiler. Some compilers might deliberately overwrite stack memory after its released to help with debugging but in a normal release build that would be an unnecessary waste of time.