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

《C专家编程》学习笔记(对内存的思考)

2014-07-06 19:43 225 查看
一、Intel 80X86系列处理器

1、80X86系列处理器的发展(P138 图7.1)

2、80X86系列芯片的构成及寻址

1)、把处理器、时钟驱动器和控制器整合到一块芯片上,其使用了芯片整合技术。

2)、通过重叠两个16位的字来形成20位地址进行寻址。

3、80X86地址模式

1)、保护模式以及32位的保护模式。

2)、虚拟的8086模式。

4、80X86内存模式及工作原理

1)、最基本的内存模式——一块16KB的内存区域所组成的段。

2)、工作原理——由一个段寄存器的值加上16位的偏移地址所组成的地址是内存地址。

3)、不同的段地址和偏移地址形成的指针可能指向同一个内存地址。

4)、计算机系统的真正挑战不在于内存的容量,而是内存的速度。

注意:为了预防会出现两个位模式不同但指向同一个内存地址的指针被错误地比较为不相等,C语言编译器设计者必须确定,在PC中这些指针是以规范的方式进行比较的。

二、虚拟内存

1、概念:只是对多层存储进行扩充,使用磁盘而不是主存来保存运行进程的映像。

2、虚拟内存通过“页的形式组织。页就是操作系统在磁盘和内存之间移来移去或进行保护的单位。,一般为几K字节。

3、进程只能操作位于物理内存的页面中。

三、Cache存储器

1、Cache位于CPU和内存之间,是一种极快的存储缓冲区,是多层存储概念的更深扩展。

2、Cache包含一个地址的列表以及他们的内容。

3、Cache的组成(P150 表7-1)。

四、数据段和堆

1、数据段能够根据需要自动增长的包含了一个对象,这个对象就是堆。

2、堆区域用于动态分配的存储且堆中的所有东西都是匿名的,不能按名字直接分配,只能通过指针间接访问。

3、对内存的回收不必与他所分配的顺序一致。,注意无须的malloc/free最终会产生对碎片。

4、堆的末端由一个称为break的指针来标识,但堆管理器需要更多的内存时,,它可以通过系统调用brk和sbrk来移动break指针。

5、内存管理的调用

1)、malloc和free:从堆中获得内存以及吧内存返回给堆。

2)、brk和sbrk:调整数据段的大小至一个绝对值(通过某个增量)。

五、内存泄漏

1、堆常会产生两种内存的问题

1)、释放或改写正在使用的内存(称为内存毁坏)。

2)、未释放不再使用的内存(称为内存泄漏)。

2、避免内存泄漏

1)、每次调用malloc函数时,在以后都要调用相应的free来释放它。

2)、使用alloca来分配动态内存,当离开调用的alloca的函数时,他所分配的内存会自动释放。

3、泄露的内存往往比忘记释放的数据更大。

4、检测内存泄漏的方法。

1)、使用swap命令来观察还有多少可用的交换空间。

2)、用“ps-lu用户名”命令来显示所有进程的大小,确定可疑的进程。

六、总线错误和段错误

1、总线错误和段错误在不同的操作系统版本上各有不同。

2、总线错误

1)、总线错误几乎都是由于未对齐的读或写引起的。

2)、对齐:数据项只能存储在地址是数据项大小的整数倍的内存位置上。

3)、编译器通过自动分配和填充数据来进行对齐。

3、段错误

1)、段错误是由内存管理单元的异常所引起的,该异常通常由于解除引用一个未初始化或非法值的和指针引起的。

2)、如果未初始化的指针恰好具有未对齐的值,他将产生总线错误,而不是段错误。

3)、导致段错误的原因

A、解除引用一个包含非法值的指针。

B、解除引用一个空指针(常常由于从系统程序中返回空指针,并未检查就引用)。

C、在未得到正确的权限是进行访问。(例如试图往一个只读的文本段存储值)

D、用完了堆栈或堆空间。

4、可能导致段错误的常见编程错误

1、坏指针值错误。

1)、在指针赋值之前就用它来引用内存。

2)、向库函数传送一个坏指针。

3)、对指针释放之后在访问它的内容。

2、改写错误

1)、越过数组边界写入数据。

2)、在动态分配的内存两端之外写入数据。

3)、改写一些堆管理数据结构。(在动态分配的内存之前的区域写入数据)

3、指针释放引起的错误

1)、释放同一个内存块两次。

2)、释放一块未曾使用malloc分配的内存。

3)、释放乃在使用中的内存。

4)、释放一个无效指针。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: