关于内存分配总觉得云里雾里,但是它却无处不在,C、C++、操蛋系统、变异原理、Linux、计算机组成原理等,他都有出席,让人甚是蛋疼。
我们的变异原理老师特别喜欢考察我们内存分配关于函数调用那部分的知识并举一些看似很简单却不简单的例子。
这段时间也一直在研究这个,下午总算想明白了一些东西。
在开始分析前,先来看一段代码:
#include <stdio.h>
#include <string.h>
int *A() {
int a = 10;
return &a;
}
void B() {
int b = 20;
}
void C() {
int c = 10;
}
int main()
{
int *ptr;
ptr = A();
B();
printf("Test1: %d\n", *ptr);
ptr=A();
printf("Test2: %d\n",*ptr);
printf("Test2: %d\n",*ptr);
ptr=A();
printf("helloworld\n");
printf("Test3: %d\n", *ptr);
}
这会输出什么呢?
如果不仔细想,就会相当当然地想输出
Test1: 10
Test2: 10
Test2: 10
helloworld
Test3: 10
实际与次相差甚多,输出为:
Test1: 20
Test2: 10
Test2: 2510836
helloworld
Test3: 0
首先明确几点:
1、C/C++将内存分为代码区和数据区,数据区包括静态区和动态区,动态区包括栈区和堆区。
2、指针变量,更一般的说局部变量放在栈区,为指针分配的空间存放在堆区,静态变量存放在静态区。
3、每次进行函数调用,都会中断调用函数,进行现场保护(包括记录当前地址、被调用函数执行完之后的指令等),然后执行被调用函数,此时为被调用函数分配一块栈空间,当被调用函数执行完后,系统将回收这块栈空间。