内存结构

0.代码段:存放函数二进制代码的区域;

1.RO DATA只读数据段(静态区域):存储不可改变的常量,无论局部还是全局的;

2.RW DATA读写数据段(静态区域):存储可改变的,全局变量(前提是定义的时候直接初始化),或者用static修饰的局部变量(也需要先初始化):static只在当前的{}程序代码段中有效;

3.BBS未初始化数据区(静态区域):分为全局和局部的区别,都会放在这里,只有初始化后,才会放到对应的栈或者RW,RO DATA,(定义的时候即初始化除外)静态区域的未初始化的变量存放在这里,存放未初始化的变量平时没有的,在程序运行时动态生成(所以平时exe里面不包含这个的大小),需编译器明确指定大小(因为未初始化);

4.函数内部局部变量,不用static或const申明的,都放在栈上,栈上的数据会自动释放。主要存储:局部变量,形参,返回值,变量空间在函数开始前开辟,结束后回收;

5.用malloc,free的都放在堆上面,可以随时申请,需要主动释放:
应用:
const char *ptrConst = "fdsfadf"; 字符串常量放在RO DATA,而加了const修饰的指针,由于是全局的,肯定在静态区域(RO DATA),但是ptrConst指向的内容不可改变,本身指向的地址是可变的,所以ptrConst放在RW DATA (这里是指全局情况,如果是局部这么定义,ptrConst会存储在栈上面;
const char const *ptrConst = "fdsfadf"; 这样两者都会放在RO DATA;
const char a[] = "fsdfds"; 数组不同于指针,两个都放在RO DATA,可以认为数组完全等价于"fsdfsds",不可改变;
const指针: const char *p = XXX p可变,*p是const;
const (char *)p = XXX p是const,*p可变;
const char * const p = xxx 最强约束,都是const 即const离那个近,哪个就是const了,但还可以直接放在后面:
char const *p = XXX //p可变,*p是const (char ) const p = XXX //p是const,p可变
char * const p = XXX///p是const,p可变
char const * const p = xxx //最强约束,都是const 沿着号划一条线,如果const位于的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;
如果const位于的右侧,const就是修饰指针本身,即指针本身是常量。可以根据这个规则来看上面声明的实际意义,相信定会一目了然。 注意:
①用const定义的全局变量,如果要存储,必须存储函数也指明是const才行,否则是无法从外部读取的,只能引用。
②只读数据定义的时候一般都是做完整的初始化,否则多余未初始化的空间也是无法适用的,因为在RO DATA里面

6.堆和栈:能不灵活就不灵活,这样效率相对会比较高一点
大小:栈是一个固定大小的内存空间,超过的话会提示over flow,堆则是链表,和内存大小有关;
效率:堆更加灵活,相对效率就会低很多,栈比较死板,但是效率高(堆由操作系统维护,栈是程序维护的)
栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。
堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可
能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。

注意:
(1)堆:char *s1=”hellow tigerjibo”;是在编译是就确定的 (2)栈:char s1[]=”hellow tigerjibo”;是在运行时赋值的;用数组比用指针速度更快一些,指针在底层汇编中需要用edx寄存器中转一下,而数组在栈上读取。 同样是只读数据区的数据,用数组来获取会比用指针快一点;
(2)栈:在函数调用时,第一个进栈的主函数中后的下一条语句的地址,然后是函数的各个参数,参数是从右往左入栈的,然后是函数中的局部变量。注:静态变量是不入栈的。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续执行;
(3)堆:一般是在堆的头部用一个字节存放堆的大小,后面直接存储内容,只要记住地址就可以用啦,比较灵活。
堆是操作系统存储空闲的内存空间地址的一个链表,每次申请后,从链表中找出空间》=申请大小的节点,
释放出来给程序用(多出来的部分再在链表上面生成新的节点),一般空间首部会存储本次分配的大小,这样方便free的时候,进行空间释放,释放后再次作为节点存放到链表中。 说明:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值