| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> 深入理解操作系统(29)第十章:虚拟存储器(6)垃圾收集器+C程序中常见的与内存有关的错误(包括:访问非法内存/读写未初始化的指针/越界或数组缓冲区溢出/指针优先级操作的问题/传值和传指针/野指针) -> 正文阅读 |
|
[Java知识库]深入理解操作系统(29)第十章:虚拟存储器(6)垃圾收集器+C程序中常见的与内存有关的错误(包括:访问非法内存/读写未初始化的指针/越界或数组缓冲区溢出/指针优先级操作的问题/传值和传指针/野指针) |
深入理解操作系统(29)第十章:虚拟存储器(6) 垃圾收集器+C程序中常见的与内存有关的错误(包括:访问非法内存/读写未初始化的指针/越界或数组缓冲区溢出/指针优先级操作的问题/传值和传指针/野指针)
1. 垃圾收集器的基本知识(略)垃圾收集器(garbage collector)是一种动态存储分配器,它自动释放程序不再需要的己分配块。
自动回收堆存储的过程叫做垃圾收集(garbage collection)。 垃圾收集可以追溯到John McCarthy在20世纪年代早期在MIT开发的Lisp系统。它是诸如Java、ML、Perl和Mathemauca等现代语言系统的一个重要部分,而且它仍然是一个重要的研究领
这个算法很有趣,因为它可以建立在己存在的malloc包的基础之上,为c和c++程序提供垃圾收集。 图10.52 略 2. C程序中常见的与内存有关的错误2.1 间接引用坏指针(访问非法内存,段错误)在进程的虚拟地址空间中有较大的洞,没有映射到任何有意义的数据。
常见示例:
假设我们想要使用scanf从stdin读一个整数到一个变量。做这件事情正确的方法是传递给scanf一个格式串和变量的地址:
然而,对于c程序员初学者而言(对有经验者也是如此!),很容易传递的内容.而不是它的地址:
在这种情况下,scanf将把val的内容解释为一个地址,并试图将一个字写到这个位置。在最好的情况下,程序立即以异常终止。在最糟糕的情况下,的内容对应于虚拟存储器的某个合法的读/写区域,于是我们就盖了存储器,这通常会在相当以后造成灾难性的,令人困感的后果。 2.2 读未初始化的存储器(读写未初始化的指针)虽然.bss存储器位置(诸如未初始化的全局c变量)总是被加载器初始化为零,但是对于堆存储器却并不是这样的,
例子:
在这个示例中,程序员不正确地假设向量Y被初始化为零。正确的实现方式是在malloc后memset一下,或者使用calloc。 2.3 允许栈缓冲区溢出(数组缓冲区溢出)如果一个程序不检查输入串的大小就写入栈中的目标缓冲区,那么这个程序就会有缓冲区溢出错误(buffer overflow bug)。
修改:
2.4 假设指针和它们指向的对象都是相同大小的
这里的目的是创建一个由个指针组成的数组,每个指针都指向一个包含m个int的数组。然而,因为程序员在第2行将sizeof(int*)写成了sizeof(int),代码实际创建的是一个int的数组。
如果我们在像Alpha这样的机器上运行这段代码,其中指针大于int,那么for循环将写到超出数组末端的地方。因为这些字中的一个很可能是己分配块的边界标记脚部,所以我们可能不会发现这个错误,直到我们在这个程序的后面很久释放这个块时,此时,分配器中
2.5 造成错位错误(越界或者缓冲区溢出)错位(Off-by-one)错误是另一种很常见的覆盖错误发生的原因:
这是前面一节中程序的另一个版本。区别就是for循环初始化的时候多加了一个等号,在这个过程中覆盖了数组后面的某个存储器。 2.6 引用指针,而不是它所指向的对象(指针优先级操作的问题)如:
后置自减运算符和取值运算符优先级相同,所以从右向左结合,先进行–,后进行*
参考: 运算符优先级
https://blog.csdn.net/lqy971966/article/details/99682879 2.7 误解指针运算(指针的算术操作是以它们指向的对象的大小为单位来进行的)
例如,下面函数的目的是扫描一个int的数组,并返回一个指针,指向val的首次出现:
然而,因为每次循环时,第2行都把指针加了4(一个整数的字节数),函数就不正确地扫描数组中每4个整数。 这个参考:
参考:指针数组和数组指针 2.8 引用不存在的变量(函数参数的传值和传指针)
如下列所示:
编译错误:
这个函数返回一个指针(比如说是p),指向栈里的一个局部变量。然后弹出它的栈帧。 1.参考:函数参数的传值和传指针(引用)(1)基本概念 2.参考:函数参数的传值和传指针(2)扩展getmemery 问题 3.扩展:字符数组和字符常量指针的区别
https://blog.csdn.net/lqy971966/article/details/99599751 2.9 引用空闲堆块中的数据(free之后还能使用 野指针)2.9.1 free内存之后的例子:
编译,执行都ok。
如果加上 p=NULL;则段错误
说明:
参考: 2.9.2 通俗易懂说明:
2.9.3 野指针:
参考:C语言中的野指针问题 2.10 引起存储器泄露(没有free导致的内存泄露)malloc之后忘记free导致内存泄露 参考:linux 开源内存泄露检测工具: valgrind 3. 一些关于虚拟存储器的关键概念(java诞生原因之一:虚拟存储器)在这一章里,我们已经看到了虚拟存储器是如何工作的,系统如何用它来实现某些功能,例如加载程序、映射共享库以及为进程提供私有受保护的地址空间。我们还看到了许多应用程序正确或者不正确地使用虚拟有储器的方式。 3.1 一个关键的经验教训是,
正如我们从对动态存储分配器的研究中学到的那样,管理拟存储器资源可能包括一些微妙的时间和空间的平衡另一个关键的经验教训是,在C程序中很容易犯与存储器有关的错误。坏的指针值、释放己经空闲了的块、不恰当的强制类型转换和指针运算,以及覆盖堆结构,这些只是可能给我们带来麻烦的许多方式中的一小部分。 3.2 java诞生原因之一:虚拟存储器
4. 第十章总结
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 11:34:53- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |