内存四区建立
代码语言:javascript复制流程说明:
1、操作系统把物理硬盘代码load到内存
2、操作系统把c代码分成四个区
3、操作系统找到main函数入口执行
各区元素分
函数调用模型
文字说明:
代码语言:javascript复制将操作系统运行状态入栈,
将main函数的返回地址入栈,
将main函数的参数入栈,
将main函数的运行状态入栈,
里面有fa函数,
将fa函数的返回地址入栈,
将fa函数的参数入栈,
将fa函数的运行状态入栈,
里面有fb函数,
将fb函数的返回地址入栈
将fb函数的参数入栈
然后逆序出栈
内存四区模型和函数调用模型变量传递分析
代码语言:javascript复制1、一个主程序有n函数组成,c 编译器会建立有几个堆区?有几个栈区?
2、函数嵌套调用时,实参地址传给形参后,C 编译器如何管理变量的生命周期?
分析:函数A,调用函数B,通过参数传递的变量(内存空间能用吗?)
那么 fa申请的内存,可以被main使用吗?
静态储存区理解:
代码语言:javascript复制#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
char * getStr1()
{
char *p1 = "abcdefg2";
return p1;
}
char *getStr2()
{
char *p2 = "abcdefg2";
return p2;
}
void main()
{
char *p1 = NULL;
char *p2 = NULL;
p1 = getStr1();
p2 = getStr2();
//打印p1 p2 所指向内存空间的数据
printf("p1:%s , p2:%s n", p1, p2);
//打印p1 p2 的值
printf("p1:%d , p2:%d n", p1, p2);
printf("hello...n");
system("pause");
return ;
}
程序的静态区模型(简化)
堆栈区理解:
代码语言:javascript复制#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
//堆
char *getMem(int num)
{
char *p1 = NULL;
p1 = (char *)malloc(sizeof(char) * num);
if (p1 == NULL)
{
return NULL;
}
return p1;
}
//栈
//注意 return不是把内存块 64个字节,给return出来,而是把内存块的首地址(例如内存的标号0xaa11) ,返回给 tmp
// 理解指针的关键,是内存. 没有内存哪里有指针
char *getMem2()
{
char buf[64]; //临时变量 栈区存放
strcpy(buf, "123456789");
//printf("buf:%sn", buf);
return buf;
}
int main()
{
char *tmp = NULL;
tmp = getMem(10);
if (tmp == NULL)
{
return 0;
}
strcpy(tmp, "111222333"); //向tmp做指向的内存空间中copy数据
printf("hello..tmp:%s.n", tmp);
system("pause");
return 0;
}
程序的堆栈区模型(简化)
测试stack生长方向
代码语言:javascript复制#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
//栈的开口向上向下,,测试 release和dubug;
//一般认为:栈开口向下
//不管栈开口向上还是向下,buf的内存地址buf 1,永远向上的..
int main()
{
int a;
int b ;
char buf[128]; //静态联邦的时候 buf所代表的内存空间的标号 就已经定义下来了....
printf("&a:%d , &b: %d n", &a, &b);
system("pause");
return 0;
}
图示
膜拜大佬请点击阅读原文