您的位置:首页 > 编程语言 > C语言/C++

C/C++笔记(C语言重要问题重讲,内存四区篇)

2016-07-18 20:08 411 查看

引.数据存哪里?

<span style="font-size:14px;">#include <stdio.h>
int main()
{
int a = 10;//a存哪里? 10存哪里?
return 0;
}</span>


解析int a =10;
int  给编译器看的,让编译器分配空间与计算
a 内存标号,上一篇讲过
= 10 这里是初始化的值,不是赋值

都堆内存里,那内存是个什么结构?

问题1.C/C++内存怎么划分

这就是操作系统内核空间 示意图。C/C++的强大之处在于可以直接转化为汇编语言。这意味着可以操作全部的

操作系统内核空间
栈(stack),向下增长
Unused
动态链接库
Unused
堆(heap),向上增长
静态读写区(.data, .bss)
只读区(.init, .rodata, .text)
保留区
下面我们将分区详细讲解,但是请注意:这里的堆不要与数据结构中我们理解的堆

栈区(stack):向下增长。由编译器自动分配释放,存放函数的参数值,局部变量的值等。
堆区(heap):向上增长。一般由程序员分配释放(动态内存申请与释放),若程序员不释放,程序结束时由操作系统回收。
全局区,静态区(static):全局变量与静态变量放在一起。初始化的放在一起,未初始化的放在一起。程序结束后由操作系统回收。
常量区(static):字符串常量和其他常量的存储位置。程序结束后由操作系统回收。
程序代码区

一、常量区(注意,这里的区域不能修改,可以取用)

#include <stdio.h>
#include <stdlib.h>

int main()
{
char *p = "12345";
char *q = "123456";
printf( "*p is %s,*q is %s\n", p, q);
printf( "*p:%d,*q:%d\n", p, q);
system( "pause");
return 0;
}




这里字符串“12345”,“123456”存放的地方就是静态存储区内存地址分别为19684056与19683796
如果将char *q
= "123456" ;改为 char *q
= "12345" ;



居然一样了,看来静态存储区很NB。如同安卓的string.xml一样。

Once more:
我们用编译器Code::Blocks重跑一下,观察内存



我们发现字符串这个中程序中的字符串(12345.123456.*p is %s,*q is %s.)全在里面,而且相互邻近。注意:这块区域申请后不能修改。

二、栈区与堆区(因为翻译问题,这里与数据结构的堆栈不同,需要更新理解)

C/C++可以在栈上分配内存,也可以在堆上分配内存

堆区:目前我们可用new,malloc两种方式申请堆区,比较简单
栈区:我们常用栈区,后面会细讲
栈区详解:

1. 栈的增长

一般认为栈是开口乡向下的。往地址小的地方延展。为了要避免栈的溢出。但画数组增长(int buf[128])时会有不同情况,从地址小到地址大的地方发展,所以这就有溢出攻击一说。
静态编译时buf所代表的内存空间标号就已经定义下来了。注意:栈增长与数组增长是不同的方向:



堆区的好处在于函数返回时常用返回指向堆区空间的方法。后面vector'会讲到。

下面两种总结常用方式:



b指向的区域是常数区。
a是数组的一种写法,放在栈区

2. 函数栈

图片来自(传智播客)



三、全局区(静态区)

上面说了这个区分为初始化的与未初始化的

1. BSS段

通俗的说,BSS是那些没有初始化和初始化为零的全局变量。它有什么特点呢,让我们看一个小程序:
int bss_array[1024*1024] = {0};
int main(int argc,char *argv[])
{
return 0;
}

变量bss_array的大小为4M, 而可执行文件的大小只有5k, 由此可见bss类型的全局变量只占运行时的内存空间,而不占文件空间。另外,大多数操作系统在加载程序时,会把所有bss全局变量全部清零,无需手工清零,但为保证程序的可移植性,手工把这些变量初始化为零也是一个好习惯。

2. DATA段

与bss相比,data 就容易明白多了,它的名字就暗示着里面存放着数据。当然如果数据全是零,为了优化考虑,编译器把它当作bss处理。通俗的说,data指那些初始化过(非零)的非const的全局变量。
int data_array[1024*1024]={1};
int main(int argc,char *argv[])
{
return 0;
}
仅仅是把初始化的值改为非零了,文件就变为4M多,由此可见,data类型全局变量是既占文件空间又占运行时的内存空间。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  读书笔记 C-C++