堆、栈与大小端存储

堆、栈与大小端存储

前言

首先先提一个和操作系统主引导相关的概念:一个有效的主引导扇区,其起始地址为0X7c00,最后两个自己的数据必须是0x55、0xaa;否则这个扇区里保存的就不是一些有意而为的数据。这三个数都是所谓的"魔数",而0x7c00的由来是这样的:虽然一个Mbr大小为512字节,但是加上堆栈区大小应该为1KB左右。而在8086CPU中0x0~0x3ff是存放中断向量表的,按照DOS1.0的32KB标准,我们最好将其放置在末尾处,大小占1KB,所以起始位置为31KB处,即0x7c00.然后再看0x55与0xaa,如果是两个单独的字节,那么低地址放0x55,高地址放0xaa;但是如果是一个字单位,呢就应该是0xaa55,这里涉及到了大小端字节序。

但是自己突然又有个问题,这里的存放顺序是大小端问题,但是数据存储又分为存在堆与栈中,这两者是怎么联系起来的?自己以前写过关于结构体内存存放的一篇文章,现在看来当时还没有想到与堆栈之间的联系,那现在来看一下数据存放与堆栈之间的关系。

大小端存储

这个概念在网络编程中应该会涉及到,虽然现在各种服务器模型和框架(事实上在设计socket网络编程之初就已经考虑了这个问题)都已经有了非常好的处理大小端存储的方式,htonl、ntohl....;但是了解一下为什么这么做也是比较重要的:

image.png

简单来说,从低地址往高地址(一般visual studio提供的内存查看方式都是这样,我们就采用这种描述方式)来看,小端会将数据的低字节部分先放入,然后放高字节部分,就比如int x=0x12345678,存放在内存中就是78 56 34 12。大端则和我们读写方式一致(从低到高地址的读写方式),同样的x存放顺序为12 34 56 78.

堆与栈

首先看一下堆与栈的结构:

image.png

堆与栈其实是在同一段地址空间的,不同的是栈是往下增长,堆是往上增长;所以说应该写道堆的数据因为太多写到栈中是合理的(虽然不应该这么做),但是因为栈是程序自动分配、堆是自己分配的,所以非常有可能会发生堆栈冲突!

在C++中,内存分成5个区,分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。

栈:就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。

堆:就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。

自由存储区:就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。

全局/静态存储区:全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。

常量存储区:这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改。

对于堆区、栈区和静态存储区它们之间最大的不同在于,栈的生命周期很短暂。但是堆区和静态存储区的生命周期相当于与程序的生命同时存在(如果不在程序运行中间将堆内存delete的话),我们将这种变量或数据成为全局变量或数据。但是,对于堆区的内存空间使用更加灵活,因为它允许你在不需要它的时候,随时将它释放掉,而静态存储区将一直存在于程序的整个生命周期中。

联系

我们分别写一个非常简单的程序来看一下0x12345678a这两个是怎么存储在内存中的:

栈中:

TIM截图20181202135611.png

堆中:

image.png

静态存储区中:

TIM截图20181202142501.png

但是自己一直觉得有问题的地方是这样的,我们都知道程序在“中断”跳转的时候是会在栈中保存程序的上下文的(返回地址、变量.....);所以我认为我们在保存结构体的时候,虽然结构体也是在编译的时候视为数据类型,然后分配在栈中。但是结构体中的成员变量的存放应该也和自身的类型有关,所以如果他们也是局部变量的时候应该也分配在栈中,其地址顺序也应该符合栈的存放方式,但是看下图:

image.png

顺序不对啊?其实这里犯了一个很大的错误,就是并没有意识到成员变量此时并不是所谓的"局部变量"了!!而是非静态成员变量,我们可以通过类的内存分配看到如下结构:

image.png

这里的x与c都是非静态成员变量,是分配在堆中的,所以可以解释了。

而成员变量和局部变量是有区别的:
a定义的位置不同
成员变量:定义于类中,作用于整个类
局部变量:定义于方法或者语句中,作用于该方法或者该语句。
b内存中出现的时间和位置不同
成员变量:当对象创建时,出现在堆内存当中。
局部变量:所属区域被运算时,出现在栈内存当中。
c生命周期不同
成员变量:随着对象的出现而出现,随着对象的消失而消失。
局部变量:随着所属区域运算结束,它就被释放。
d初始化值不同
成员变量:成员变量因为在堆内存中,所以它有默认初始值。
局部变量:没有默认的初始值。

那么如果我们在class中定义一个函数,函数中用了局部变量,那么这个类中非静态成员函数的局部变量是符合我们说的数据存放规则的么?答案是:是的!

image.png

这里引用一下总结的静态成员变量与非静态成员变量的区别:

1、从保存位置:
a) 静态成员变量: 方法区的静态区域
b) 非静态成员变量: 堆内存中的对象空间里面

2、从书写格式上看:
a) 静态成员变量: 在数据类型前面多了一个static修饰
b) 非静态成员变量: 没有static修饰

3、从生命周期上看:
a) 静态成员变量:  在类加载的时候,类加载完成,就分配完空间;直到类被卸载时空间被回收
b) 非静态成员变量: 创建对象的时候分配空间; 对象变为垃圾空间被回收的时候被销毁

4、从使用方法上看:
a) 静态成员变量:  直接通过类名使用
b) 非静态成员变量: 必须通过对象使用

5、从修改后的影响范围上看:
a) 静态成员变量: 对该类的所有对象都有影响;
b) 非静态成员变量:  只对一个对象有影响

结语

其实写完以后发现其实并不需要纠结的,就是根据变量类型按照堆或栈的顺序存储,然后再根据数据大小分成字节,再按字节序存储就行了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,869评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,716评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,223评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,047评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,089评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,839评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,516评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,410评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,920评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,052评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,179评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,868评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,522评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,070评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,186评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,487评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,162评论 2 356

推荐阅读更多精彩内容

  • 1. 基础知识 1.1、 基本概念、 功能 冯诺伊曼体系结构1、计算机处理的数据和指令一律用二进制数表示2、顺序执...
    yunpiao阅读 5,319评论 1 22
  • 喜欢的话记得点赞 一、内存管理:移动设备的内存及其有限,每一个APP所能占用的内存是有限制的二、什么行为会增加AP...
    蓝白七七阅读 2,012评论 1 12
  • 我,一名高二在校学生,没有多丰富的经历,更没有优秀的写作能力,我只希望,在这上面,能够不定时分享一些我的文章,以此...
    sfyypakl阅读 204评论 0 0
  • 五月不期而至 敲打着菖蒲的门 一声声叩问 一壶酒 是浊,是清? 一江月 是浮,是沉? 看汨罗江畔 谁弹九歌赋离骚 ...
    金指尖的花园阅读 156评论 0 3