C/C++ 函数的内存管理
C/C++ Memory Management for Functions
假设有一个带有全局函数的 one cpp 文件。
据我所知,当我 运行 程序时,指令集被复制到内存,并一直留在那里直到程序结束。每次我调用一个函数时,变量的虚拟地址都是相同的,但我无法理解它首先分配内存并且在程序结束之前不释放或者它为我每次调用函数分配内存。
编辑:我在除 main 之外的其他函数中调用函数,地址已更改。所以问题是错误的。对不起。
局部变量通常结束于一个叫做 stack that is statically allocated when the program (or thread) starts. If you always call the function with the same call stack 的东西,局部变量往往会结束在堆栈中的相同位置,因此为不同的调用分配相同的虚拟地址。
请注意,从技术上讲,none 这种行为是在 c or c++ 语言规范中指定的,这正是当今大多数现代平台最终实现的方式。
在 C 和 C++ 的典型实现中,局部变量的存储在进入函数时在 堆栈 (参见:Stack-based memory allocation)上分配,并从当函数 returns.
时堆栈
您看到一个函数在不同的调用中为其变量使用相同的地址实际上是巧合。尝试将您的函数调用嵌套在其他调用中,看看会发生什么:
#include <stdio.h>
int funcTwo()
{
int nn = 5;
printf("funcTwo, &nn = %p\n", &nn);
}
int funcOne(int n)
{
int nn = n;
printf("funcOne, &nn = %p\n", &nn);
funcTwo();
}
int main(int argc, char **argv)
{
funcOne(5);
funcTwo();
return 0;
}
示例输出:
funcOne, &nn = 0x7fff96726b7c
funcTwo, &nn = 0x7fff96726b4c
funcTwo, &nn = 0x7fff96726b7c
观察 &nn
在对 funcTwo
的两次调用中略有不同。这是因为一个实例是从 funcOne
内部调用的,它在堆栈上有自己的局部变量(以及它的参数 return 地址和用于保存处理器寄存器值的任何其他 space例如)。额外的堆栈使用将 funcTwo
中的变量地址推到堆栈的更上层(到较低的地址,因为堆栈在此架构上向下增长)。
假设有一个带有全局函数的 one cpp 文件。
据我所知,当我 运行 程序时,指令集被复制到内存,并一直留在那里直到程序结束。每次我调用一个函数时,变量的虚拟地址都是相同的,但我无法理解它首先分配内存并且在程序结束之前不释放或者它为我每次调用函数分配内存。
编辑:我在除 main 之外的其他函数中调用函数,地址已更改。所以问题是错误的。对不起。
局部变量通常结束于一个叫做 stack that is statically allocated when the program (or thread) starts. If you always call the function with the same call stack 的东西,局部变量往往会结束在堆栈中的相同位置,因此为不同的调用分配相同的虚拟地址。
请注意,从技术上讲,none 这种行为是在 c or c++ 语言规范中指定的,这正是当今大多数现代平台最终实现的方式。
在 C 和 C++ 的典型实现中,局部变量的存储在进入函数时在 堆栈 (参见:Stack-based memory allocation)上分配,并从当函数 returns.
时堆栈您看到一个函数在不同的调用中为其变量使用相同的地址实际上是巧合。尝试将您的函数调用嵌套在其他调用中,看看会发生什么:
#include <stdio.h>
int funcTwo()
{
int nn = 5;
printf("funcTwo, &nn = %p\n", &nn);
}
int funcOne(int n)
{
int nn = n;
printf("funcOne, &nn = %p\n", &nn);
funcTwo();
}
int main(int argc, char **argv)
{
funcOne(5);
funcTwo();
return 0;
}
示例输出:
funcOne, &nn = 0x7fff96726b7c
funcTwo, &nn = 0x7fff96726b4c
funcTwo, &nn = 0x7fff96726b7c
观察 &nn
在对 funcTwo
的两次调用中略有不同。这是因为一个实例是从 funcOne
内部调用的,它在堆栈上有自己的局部变量(以及它的参数 return 地址和用于保存处理器寄存器值的任何其他 space例如)。额外的堆栈使用将 funcTwo
中的变量地址推到堆栈的更上层(到较低的地址,因为堆栈在此架构上向下增长)。