《C++编程艺术》第二章的垃圾回收器 源码Bug修改

《C++编程艺术》上第二章的代码运行第一个测试程序的时候就报错了,上网找了下,没找到具体的解决方法,CSDN上有网友说是在collect里面出的错。

好吧,我自己动手调进去修改吧。

#include <iostream>
#include <new>
#include "gc.h" 

using namespace std; 

int main() {
    GCPtr<int> p; 

    try {
        p = new int;
    } catch(bad_alloc exc) {
        cout << "Allocation failure!\n";
        return 1;
    } 

    *p = 88; 

    cout << "Value at p is: " << *p << endl; 

    int k = *p; 

    cout << "k is " << k << endl; 

    system("pause");

    return 0;
}

在这个函数上单步调试了下,发现到最后return 0那步才引起的中断,看来确实是collect函数出的错。

 1 template <class T, int size>
 2 bool GCPtr<T, size>::collect() {
 3     bool memfreed = false;        //是否有内存被释放的标记
 4
 5 #ifdef DISPLAY
 6     cout << "Before garbage collection for ";
 7     showlist();
 8 #endif
 9
10     list<GCInfo<T> >::iterator p;
11     //这里用两层循环,每次释放了内存后,都要从头对gclist进行再次搜索
12     do {
13
14         // 扫描gclist查找是否有refcount为0的条目,当找到这种条目时
15         // 调用remove函数删除它,remove是STL list类的一个成员
16         for(p = gclist.begin(); p != gclist.end(); p++) {
17             if(p->refcount > 0)
18                 continue;
19
20             memfreed = true;
21
22
23
24             // 释放空指向的内存地址
25             if(p->memPtr) {
26                 if(p->isArray) {
27 #ifdef DISPLAY
28                     cout << "Deleting array of size "
29                         << p->arraySize << endl;
30 #endif
31                     delete[] p->memPtr;    // 释放数组
32                 }
33                 else {
34 #ifdef DISPLAY
35                     cout << "Deleting: "
36                         << *(T *) p->memPtr << "\n";
37 #endif
38                     delete p->memPtr;        // 释放当个对象
39                 }
40
41             }
42             // 从gclist中删除空指向的条目.
43             gclist.remove(*p);
44
45             // 重新搜索
46             break;
47         }
48
49     } while(p != gclist.end());
50
51 #ifdef DISPLAY
52     cout << "After garbage collection for ";
53     showlist();
54 #endif
55
56     return memfreed;
57 }   

注:上面是修改好的代码

进collect函数后发现,执行gclist.remove(*p);  这步后,后面的p->refcount,p->isArray等信息全错了,突然醒悟过来,

因为这步释放了p节点,而后面还要读取p节点的相关信息,因此导致错误发生。正确的做法是先对p节点进行读取refcount,

isArray等信息,然后释放p中的memptr指针,最后对p节点进行释放。修改好的代码如上所示。

时间: 2024-10-30 07:10:41

《C++编程艺术》第二章的垃圾回收器 源码Bug修改的相关文章

第二章 Google guava cache源码解析1--构建缓存器

1.guava cache 当下最常用最简单的本地缓存 线程安全的本地缓存 类似于ConcurrentHashMap(或者说成就是一个ConcurrentHashMap,只是在其上多添加了一些功能) 2.使用实例 具体在实际中使用的例子,去查看<第七章 企业项目开发--本地缓存guava cache>,下面只列出测试实例: import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit;

一维向量旋转算法 编程珠玑 第二章

看了编程珠玑第二章,这里面讲了三道题目,这里说一下第二题,一维向量旋转算法. 题目:将一个n元一维向量(例数组)向左旋转i个位置. 解决方法:书上讲解了5种方法,自己只想起来2种最简单方法(下面讲的前两种). 1.原始方法. 从左向右依次移动一位,对所有数据平移:这样循环i次,算法最坏时间复杂度达n^2.耗时不推荐. 2.空间换时间. 顾名思义,申请一个i长度的空间,把前i半部分放到申请空间中,再把后面的所有数据向左移动i个位置,最后把申请的空间中的数据放到后半部分.浪费空间,不推荐. 3.杂技

编程珠玑第二章

编程珠玑第二章 A题 给定一个最多包含40亿个随机排列的32位整数的顺序文件,找出一个不在文件中一32位整数. 1.在文件中至少存在这样一个数? 2.如果有足够的内存,如何处理? 3.如果内存不足,仅可以用文件来进行处理,如何处理? 答案: 1.32位整数,包括-2146473648~~2146473647,约42亿个整数,而文件中只有40亿个,必然有整数少了. 2.如果采用位数思想来存放,则32位整数最多需要占用43亿个位.约512MB的内存空间. 可以采用前一章的位处理方法.然后判断每个in

C#编程总结(七)数据加密——附源码

C#编程总结(七)数据加密——附源码 概述 数据加密的基本过程就是对原来为明文的文件或数据按某种算法进行处理,使其成为不可读的一段代码,通常称为“密文”,使其只能在输入相应的密钥之后才能显示出本来内容,通过这样的途径来达到保护数据不被非法人窃取.阅读的目的. 该过程的逆过程为解密,即将该编码信息转化为其原来数据的过程.加密建立在对信息进行数学编码和解码的基础上.加密类型分为两种,对称加密与非对称加密,对称加密双方采用共同密钥.非对称加密,这种加密方式存在两个密钥,一个是公共密钥(对外公开),一种

第66讲:Scala并发编程实战初体验及其在Spark源码中的应用解析

王家林亲授<DT大数据梦工厂>大数据实战视频“Scala深入浅出实战经典”视频.音频和PPT下载!第66讲:Scala并发编程实战初体验及其在Spark源码中的应用解析百度云:http://pan.baidu.com/s/1pJ5jzHx腾讯微云:http://url.cn/aSawrm360云盘:http://yunpan.cn/cctL3QYACaVNa  访问密码 c0fb 信息来源于 DT大数据梦工厂微信公众账号:DT_Spark

java编程思想 第二章

这篇时间较之前篇章时间靠后,是由于,某一天晚上看完Java编程思想文献之后来不及做笔记了. 以下笔记基本为转载,不是原创 第二章   一切都是对象 目录: 2.1 用引用操纵对象 2.2 必须由你创建所有对象 2.3 永远不需要销毁对象 2.4 创建新的数据类型:类 2.5 方法.参数和返回值 2.6 构建一个Java程序 2.7 你的第一个Java程序 2.8 注释和嵌入式文档 2.9 编码风格 2.1 用引用操纵对象 一切都看作对象,操纵的标识符实际上是对象的一个“引用”,遥控器(引用)操纵

JavaScript DOM编程艺术第一章:JavaScript简史

本系列的博客是由本人在阅读<JavaScript DOM编程艺术>一书过程中做的总结.前面的偏理论部分都是书中原话,觉得有必要记录下来,方便自己翻阅,也希望能为读到本博客的人提供一些帮助,所以 如果您也看过这本书,希望不要喷小的"抄袭",其实我也懒得敲这些文字也想简单粗暴地上代码,但是只有实践没有理论不容易自己理解,为避免误导,该"抄"的地方还是要"抄"的,哈哈~~ 一.JavaScript的起源 JavaScript是Netscap

JavaScript DOM编程艺术第二版学习(1/4)

---恢复内容开始--- 接下来项目需要网页相关知识,故在大牛的指引下前来阅读本书. 当前水平:HTML&CSS&JS基本掌握,能在阅读文档以及Google查找的情况下完成前端代码编写,但是学习不深,HTML5&CSS3新特性.JS基础&框架皆不熟悉 读书目的:了解DOM概念并通过训练熟悉掌握,了解JS特性 博客目的:督促自己学习并记录下过程 博客编写时读书进度:第6章完结 阅读规划: 浏览目录之后,总结该书学习思路大致如下(其实就是生搬目录): 简史->最基础语法-

集体智慧编程_第二章(提供推荐)_1

前言:最近正在拜读Toby Segaran先生写的集体智慧编程,首先感谢Toby Segaran先生将知识以书本的方式传播给大家,同时也感谢莫映和王开福先生对此书的翻译,谢谢各位的不辞辛苦.首先在写随笔之前,跟各位分享一下我的编程环境:win7系统,python版本是2.7.10,开发环境我选择的是pycharm程序.本书的第一章为集体智慧导言,主要介绍的何为集体智慧和机器学习的相关概念和其局限性,以及与机器学习相关的例子和应用场景.下面开始机器学习第二章--提供推荐的相关内容. 本章主要内容: