接上篇内存四区的堆区的总结,下面做一些栈区的相关总结。

一、栈区的分析:

就下面测试程序

#include "stdio.h"
#include "string.h"
char *getMem()
{
char buf[]; strcpy(buf, "aabbccdd"); return buf;
}
int main(int argc, const char **argv)
{
char *tmp = NULL;
tmp = getMem2();
printf("tmp = %s\r\n", tmp);
return ;
}
先进行程序的编译,会出现如下的警告:
​图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 ;
}
编译运行后,可以看出来,a的地址为0060FF2C,大于b的地址0060FF28,那说明栈的开口方向是向下的。

其实在一般情况下,默认认为栈的开口向下的,主要是因为:每个应用程序的栈,如果提前把栈的最大值定义好,在程序逐渐入栈的过程中,栈的地址越来越小,避免栈的溢出。

​图5 运行效果图

2、栈的属性和内存块的地址增长方向是不同的概念

比如下面的测试程序。

#include <stdio.h>
int main(int argc, const char **argv)
{
char buf[]; printf("buf = %p, buf + 1 = %p\r\n", buf, buf + );
return ;
}

​图6 内存块在栈区的示意图

如果buf指针指向绿色的位置,那么在进行buf+1运算的时候,指针就会跑到栈的外面去了,这不应该的出现的效果呀。和我们实际需要的buf+1的效果不一致。所以,不管栈的开口方向如何,内存块(buf)的内存空间的生长方向都是向上的。

运行我们的程序可以看出来:

​图7 运行的效果图

三、简单总结

1、拷贝指的是向指针指向的内存空间拷贝,而不是向指针变量中拷贝

2、程序返回的是指针的内存的首地址,而不是整个内存空间

3、一般情况下,默认认为栈的开口向下的

4、栈的属性和内存块的地址增长方向是不同的概念

C语言内存四区的学习总结(三)---- 栈区的更多相关文章

  1. C语言内存四区的学习总结(一)---- 静态区

    最近重新学习C语言相关知识,重新提到内存四区的概念,那么在之前的学习的基础上,在这儿做一个简单的总结与分享. 一.内存四区建立的流程 可以简单直观的查看下面的这个图片,直接的说明我们的程序在内存中是如 ...

  2. C语言内存四区的学习总结(二)---- 堆区

    接上篇,内存四区的分析-静态区,下面来说明一下堆区总结. 堆区分析: 堆区(heap):一般由程序员分配释放(动态内存申请与释放),若程序员不释放,程序结束时可能由操作系统回 就下面的程序: #inc ...

  3. C语言内存四区

    按照老版操作系统来学习,内存对于程序来讲分四区.分别是 代码区,静态区,栈,堆. 由上面程序执行的结果可知: 貌似结果就是 静态代码堆栈 静态区存放的是程序中所有静态变量和常量的值.静态区的大小是程序 ...

  4. c语言内存四区、数据存储范围和内存存储方向

    (1)代码区通常是共享只读(代码无法修改)的,即可以被其他的程序调用,例如运行两个qq,除了数据不一样,代码都是一样的, 每次运行qq,都会将代码和数据加载到内存中,除了数据,每次加载的代码都是一样的 ...

  5. C语言提高 (1) 第一天 数据类型本质与内存四区

    (物联网的分层的概念 b/s c/s 结构 习惯: 在C语言 0 函数执行成功 <0是错误 >1做一些返回值处理 3 课前准备 工作经验,记录 4 数据类型的本质 数据类型的本质是固定大小 ...

  6. 深入理解C语言-深入理解内存四区

    数组与指针 当数组做函数参数的时候,会退化为一个指针 此时在函数内是得不到数组大小的 因此,数组做函数参数的时候需要传递数组大小,也就是多传递一个参数 void func(int arr[], int ...

  7. C语言进阶之路(一)----C语言的内存四区模型

    内存四区模型:操作系统给C/C++编写的程序分配内存,通常将分配的内存划分为以下四个区域:1.栈区:存放局部变量,用完由操作系统自动释放2.堆区:动态分配给程序的内存区域,由程序员手动释放3.数据区: ...

  8. C语言之内存四区模型和函数调用模型

      内存四区模型 流程说明1.操作系统把物理硬盘代码load到内存2.操作系统把c代码分成四个区3.操作系统找到main函数入口执行 1.内存四区: 一个由c/C++编译的程序占用的内存分为以下几个部 ...

  9. C语言的内存四区模型和函数调用模型

    首先是操作系统将代码程序加载到内存中 然后将内存分为4个区 栈区,程序的局部变量区,函数传递的参数,由编译器自动进行内存资源的释放. 堆区,动态内存申请,如果不手动释放内存,则这块内存不会进行析构. ...

随机推荐

  1. Echart ,X轴显示的为tooltip内显示的一部分内容放在上面显示的一部分如下图所示

    如图所示:X轴只显示tooltip部分内容解决方案 在xAxis下面,实现方法如下 axisLabel: { interval: 0, formatter:function(value) { var ...

  2. IDEA与eclipse:vm参数调优笔记

    我的电脑配置12G内存,64位,win10系统. 首先,idea,是在idea中安装目录下的bin目录下面找到位的同学注意找到idea32.exe.vmoptions的文件去编辑. 更改文件,无非大多 ...

  3. 【Debug】串口发送数据时部分字节被拉长,出现帧错误,原因MCU进入低功耗模式导致串口时钟停了!

    串口发送数据时部分字节被拉长,出现帧错误,原因MCU进入低功耗模式导致串口时钟停了!

  4. javaSE基础知识

    JVM,JRE,JDK三者的简单总结 1.见名解释 Java虚拟机(JVM):Java virtual machine简称JVM:“virtual”中文意思“虚拟的”,“machine”中文意思“机器 ...

  5. WordCount编码实现及单元测试(第二次作业)

    项目码云地址:https://gitee.com/zhujunlin/wc.git 一.题目思路 ========== 阅读完题目要求之后我很懵,因为之前从未使用过博客园和码云工具,对编程的目标需求也 ...

  6. Jquery 字符串转数字

    其实在jquery里把字符串转换为数字,用的还是js,因为jquery本身就是用js封装编写的. 比如我们在用jquery里的ajax来更新文章的阅读次数或人气的时候,就需要用到字符串转换为数字的功能 ...

  7. 如何利用webpack4.0搭建一个vue项目

    作为一个初学者,记录自己踩过的坑是个好的习惯.我本身比较懒,这里刚好有时间把自己的搭建过程记录一下这里是参考文章   https://www.jianshu.com/p/1fc5b5151abf文章里 ...

  8. Unity中建立文本保存数据

    public void CreateYunYD() { GameToolsManager.Instance.effectType = EFFECTTYPE.YunYD; CreateYunOrWu(& ...

  9. php的trie_filter扩展安装敏感词查找

    #编译libiconv ./configure make make install #编译libdatrie-0.2.11 ./configure LDFLAGS=-L/usr/local/lib L ...

  10. 【Spring学习】Spring的源码解析之路

    缘起:=====>>>> 在项目中实际上是用到了Spring的内容,只是直接用的SpringBoot,不管是Eclipse中还是在Intellig IDEA中,应该都比较容易能 ...