C89:论内存分配问题

学习了这么久的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不初始化,里边数据是随机的垃圾数据

 

2.realloc

 

posted @ 2019-07-08 13:27  言午丶  阅读(247)  评论(0编辑  收藏  举报