1、内存四区的建立过程:
首先操作系统将物理硬盘中的代码装载到内存中,
然后操作系统将c代码分成四个区,
最后操作系统找到main函数的入口开始执行。
2、内存四区具体分析:
栈区(stack):由编译器自动分配释放,存放函数的参数值、程序局部变量等。
堆区(heap):一般由程序员分配释放(动态内存申请和释放:malloc、new、free、delete),
若程序员不释放,程序结束时可能由操作系统回收。
全局区(静态区 static):存放全局变量和静态变量以及常量,已经初始化了的在一块区域,未初始化的在相邻的
另一块区域,该区域在程序结束后由操作系统释放。
代码区(code):存放程序的代码,由操作系统管理。
3、全局区案例理解:
char* getStr1()
{
char* p1="abcdefg";
return p1;
}
char* getStr2()
{
char* p2="abcdefg2";
return *p2;
}
void main()
{
char* p1=NULL;
char* p2=NULL;
p1=getStr1();
p2=getStr2();
printf("p1:%s,p2:%s\n",p1,p2);//打印p1、p2所指向的内存空间的数据
printf("p1:%d,p2:%d\n",p1,p2);//打印p1、p2的值}
结果很明显,p1、p2指向的内存空间的数据不一样,且p1、p2的值也不一样(即地址值)。
但是,如果将p1中的内容也改为:“abcdefg2”时,两部分的值都一样,这是因为画出内存四区图时可以看见:
要被赋值的“abcdefg2”都是存在全局区的,当C编译器发现,全局区有两个一模一样的变量时,就会对其进行优化,将两个合并成一个,这也就是为什么,两者的值全都一样的原因。
4、堆栈案例理解:
(1)堆的例子:
char *getMum(int num)
{
char *p1=NULL;
p1=(char *)malloc(sizeof(char)*num); //p1指向的内存在堆区,因此在整个程序运行中,不调用free之类的,不会自动释放。
所以,p1指向堆区时不会轻易变成野指针。
if(p1==NULL) return NULL;
return p1;
}
void main()
{
char *tmp=NULL;
tmp=getMum(10);
if(tmp==NULL) return;
strcpy(tmp,"111222"); //千万注意这句话的意思是,把111222放进tmp指针指向的内存空间里,因为那段空间
并没有释放,所以还是存在的,因此程序最终的执行结果,打印出来的是111222
printf("tmp:%s\n",tmp);
}
(2)栈的例子:
char *getMum2()
{
char buf[64]; //这些都是临时变量,存储在栈中,当getMum2函数调用结束后,会随着函数的析构而一起消失。
strcpy(buf,"123456789");
printf("buf:%s\n",buf);
}
void main()
{
char *tmp=NULL;
tmp=getMum(10); //赋值时,先调用=右边的函数,一调用完,函数中的临时变量又消失了,因此,tmp指向
的是一个无效地址,成为了野指针,所以打印的时候,出现了乱码或者不确定的数值。
printf("tmp:%s\n",tmp);}
5、一个主程序有n函数组成,C++编译器会建立几个堆区?几个栈区?
一个程序中只会有一个内存四区。