学习了这么久的C/C++,还不知道这个,我也是很羞愧~
一、操作系统的内存
操作系统的内存管理方式有:1.重定位(relocation)
2.分段(segmentation)
3.分页(paging)
4.虚拟存储(virtual memory)
而操作系统的内存上各种占用着不同的进程,每个进程占用不同的内存空间
1.内存对齐
二、进程的内存
1.栈(高地址)
从上面的图可以看到,除了最高地址的内存存放的是内核,用户无法对该内存进行修改。
而栈存放在可分配内存的最高位置,在C/C++中,栈用来存储函数参数从右到左,然后存储局部变量。
栈遵从LIFO顺序进行压栈(push)和出栈(pop),内存分配由高到低
栈是有一定容量大小的,一般1M或者2M,而且栈的速度比堆块
2.内存映射段(高地址)
在栈的下方,是内存映射段。内核将内奸内容直接映射到内存之中
3.堆(中地址)
堆用于运行时内存分配,堆用来存储那些生存期与函数无关的数据,内存分配由低到高
在C/C++中,使用malloc/free或者new/delete来分配堆内存
4.BSS段、数据段【全局数据区】(低地址)
在C/C++中,BSS段和数据段存储的都是全局变量和静态变量的内容
但是BSS段存储的是未被初始化的变量,会默认初始化为零
数据段存储的事已经初始化的变量
5.代码段【文本段】【常量区】(低地址)
包含了进程执行的程序机器语言指令,文本段具有只读属性,以防止进程通过错误指针意外修改自身的指令
也可以包含只读常量或者字符串常量
三、常见的内存错误
1.内存分配未成功,却使用了它
解决办法:在使用之前检查指针是否为NULL
2.内存分配虽然成功,但是尚未初始化就引用它
解决办法:要赋初值
3.内存分配成功并且已经初始化,但是操作越过来内存的边界
解决办法:内存越界要检查
4.忘记释放内存,造成内存泄漏
解决办法:要记得释放内存
5.释放了内存却继续使用它
解决办法:防止野指针
野指针是指向垃圾内存的指针,它不是空(NULL)指针,指向的内存区域是未可知的
四、C/C++内存分配位置
在C/C++中内存分为五个区,分别是栈 自由存储区 堆 全局/静态存储区 常量存储区,分别对应上面的进程五个区域
五、C/C++内存分配方法
1.静态分配内存
2.动态分配内存
(1)malloc/free
(2)new/delete
六.不常用的内存方法
1.calloc
void* calloc(unsigned n,unsigned size);
用calloc函数可以为一维数组开辟动态存储空间,n为数组元素个数,每个元素长度为size,函数返回值指向所分配域的起始位置的指针.如果分配不成功,返回NULL
calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据