目录
一、程序中的栈二、函数的调用过程三、函数调用的栈变化四、函数调用栈上的数据五、程序中的堆六、程序中的静态存储区七、小结一、程序中的栈
栈是现代计算机程序里最为重要的概念之一栈在程序中用于维护函数调用上下文函数中的参数和局部变量存储在栈上栈保存了一个函数调用所需的维护信息
参数返回地址局部变量调用上下文二、函数的调用过程
每次函数调用都对应着一个栈上的活动记录
调用函数的活动记录位于栈的中部被调函数的活动记录位于栈的顶部三、函数调用的栈变化
从main() 开始运行
main() 调用 f()
当从 f() 调用中返回 main()
四、函数调用栈上的数据
函数调用时,对应的栈空间在函数返回前是专用的函数调用结束后,栈空间将被释放,数据不再有效下面看一个指向栈数据的指针:
#includeint* g() { int a[10] = {0}; return a; } void f() { int i = 0; int b[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int *pointer = g(); for (i = 0; i < 10; i++) { b[i] = pointer[i]; } for(i = 0; i < 10; i++) { printf("%d\n", b[i]); } } int main() { f(); return 0; }
输出结果如下:
如果把
for (i = 0; i < 10; i++)
{
b[i] = pointer[i];
}
注释了,直接打印 pointer[i] 里面的数据,如下:
#includeint* g() { int a[10] = {0}; return a; } void f() { int i = 0; int b[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int *pointer = g(); /* for (i = 0; i < 10; i++) { b[i] = pointer[i]; } */ for(i = 0; i < 10; i++) { printf("%d\n", pointer[i]); } } int main() { f(); return 0; }
输出结果如下:
为什么直接打印 pointer[i] 里面的值会是这样呢?因为 pointer 指向的空间是栈空间,栈空间在 g() 函数返回之后,活动记录就被释放了。被释放后调用 printf 函数,printf 函数需要在栈上面建立一个活动记录。这个活动记录就会有 printf 函数的参数信息和返回值等,所以 pointer 所指向的内存里面的数据由于 printf 函数的调用被改变了。因此,不能返回局部变量的地址,不能返回局部数组的数组名。
五、程序中的堆
堆是程序中一块预留的内存空间,可由程序自由使用堆中被程序申请使用的内存在被主动释放前将一直有效为什么有了栈还需要堆?
答:栈上的数据在函数返回后就会被释放掉,无法传递到函数外部,如:局部数组
C语言程序中通过库函数的调用获得堆空间
头文件:malloc.hmalloc -- 以字节的方式动态申请堆空间free -- 将堆空间归还给系统系统对堆空间的管理方式
空闲链表法,位图法,对象池法等等
以int* p = (int*)malloc(sizeof(int)); 为例,要申请 4 个字节的大小,遍历之后发现跟 5 Bytes 这个节点最接近,找到一个可以用的单元之后,就将这个单元的地址返还给了 p 指针。以前也提过使用 malloc 申请内存空间时返回的内存空间可能比申请的实际内存空间要大一点点,原因就是在空闲链表管理堆空间这样的系统里面,它会找最近的那个,找到后的一般都大于等于所需要的内存空间,假如5 Bytes 这个节点下所有的空闲内存单元都用完的话,就会找12 Bytes 节点下的内存单元,这样malloc 返回的内存空间就有可能比自己实际申请的内存空间要大。
六、程序中的静态存储区
静态存储区随着程序的运行而分配空间静态存储区的生命周期直到程序运行结束在程序的编译期静态存储区的大小就已经确定静态存储区主要用于保存全局变量和静态局部变量静态存储区的信息最终会保存到可执行程序中下面看一个静态存储区的验证代码:
#includeint g_v = 1; static int g_vs = 2; void f() { static int g_vl = 3; printf("%p\n", &g_vl); } int main() { printf("%p\n", &g_v); printf("%p\n", &g_vs); f(); return 0; }
输出结果如下:
可以看到这三个地址是顺序存放的,因为这三个变量都是存放在程序的静态存储区,静态存储区在程序里面有固定的起始地址。
七、小结
栈,堆和静态存储区是程序中的三个基本数据区
栈区主要用于函数调用的使用堆区主要是用于内存的动态申请和归还静态存储区用于保存全局变量和静态变量到此这篇关于C语言深入讲解栈与堆和静态存储区的使用的文章就介绍到这了,更多相关C语言 栈与堆内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
X 关闭
X 关闭
- 15G资费不大降!三大运营商谁提供的5G网速最快?中国信通院给出答案
- 2联想拯救者Y70发布最新预告:售价2970元起 迄今最便宜的骁龙8+旗舰
- 3亚马逊开始大规模推广掌纹支付技术 顾客可使用“挥手付”结账
- 4现代和起亚上半年出口20万辆新能源汽车同比增长30.6%
- 5如何让居民5分钟使用到各种设施?沙特“线性城市”来了
- 6AMD实现连续8个季度的增长 季度营收首次突破60亿美元利润更是翻倍
- 7转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 8充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 9好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 10名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?