C语言内存四区的学习总结(三)---- 栈区
作者:互联网
接上篇内存四区的堆区的总结,下面做一些栈区的相关总结。
一、栈区的分析:
就下面测试程序
#include "stdio.h" #include "string.h" char *getMem() { char buf[128]; strcpy(buf, "aabbccdd"); return buf; } int main(int argc, const char **argv) { char *tmp = NULL; tmp = getMem2(); printf("tmp = %s\r\n", tmp); return 0; }
先进行程序的编译,会出现如下的警告:图1 编译警告说明示意图
警告说明的是返回局部变量或者临时变量的地址,暂时不管他,直接运行后出现效果:
图2 运行的效果图进行分析可知道其中的原委:
上面的程序,在getMem函数中,在栈区分配128字节的内存空间,在函数执行完毕返回后,将buf析构掉(浅粉色表示),并且,buf做指向的内存空间也被析构(灰色表示)。
其内存四区表示可以简单如图所示:
图3 程序运行的内存四区的变化的模型示意图所以,在打印的时候出现不认识的东西,就是由于上述原因造成的。
二、堆栈的属性
1、栈的开口方向的测试(先进后出的特性)
可以简单的进行测试,首先假设一个虚拟的方向轴,那么,在图3所示的效果中,左边的栈一代表开口方向向下,右边栈二代表开口方向向上,那么,根据先进后出的特性,如果b的地址小,那说明栈的开口方向向下。
图4 栈的开口方向的测试示意图那么可以用下面的简单程序进行测试:
#include <stdio.h> int main(int argc, const char **argv) { int a; int b; printf("&a = %p, &b = %p\r\n", &a, &b); return 0; }
编译运行后,可以看出来,a的地址为0060FF2C,大于b的地址0060FF28,那说明栈的开口方向是向下的。
其实在一般情况下,默认认为栈的开口向下的,主要是因为:每个应用程序的栈,如果提前把栈的最大值定义好,在程序逐渐入栈的过程中,栈的地址越来越小,避免栈的溢出。
图5 运行效果图2、栈的属性和内存块的地址增长方向是不同的概念
比如下面的测试程序。
#include <stdio.h> int main(int argc, const char **argv) { char buf[128]; printf("buf = %p, buf + 1 = %p\r\n", buf, buf + 1); return 0; }
图6 内存块在栈区的示意图
如果buf指针指向绿色的位置,那么在进行buf+1运算的时候,指针就会跑到栈的外面去了,这不应该的出现的效果呀。和我们实际需要的buf+1的效果不一致。所以,不管栈的开口方向如何,内存块(buf)的内存空间的生长方向都是向上的。
运行我们的程序可以看出来:
图7 运行的效果图三、简单总结
1、拷贝指的是向指针指向的内存空间拷贝,而不是向指针变量中拷贝
2、程序返回的是指针的内存的首地址,而不是整个内存空间
3、一般情况下,默认认为栈的开口向下的
4、栈的属性和内存块的地址增长方向是不同的概念
标签:栈区,开口,int,四区,C语言,char,地址,内存,buf 来源: https://www.cnblogs.com/songshuaiStudy/p/10674959.html