为什么我的软件内存占用这么高?从内存占用过高到C++内存管理方法

背景

在尝试写一个PDF文件标注软件时,需要将PDF文件转化为图片然后再展示给用户,同时允许用户在图片上做标注。

实现概况

假设用下面3各类:PDFFilePDFPageMark分别对应PDF文件,文件中的每个页面以及页面中的标注信息:

class Mark {
    Mark(QRect _pos);
    ~Mark() = default;
    void paint();
    // ...
private:
    QRect pos;
    // ...
}

class PDFPage {
public:
    PDFPage(QImage *_img);
    ~PDFPage() = default;
    void paint();
    void addMark(Mark *mark);
    // ...
private:
    QImage *img;
    std::vector<Mark*> marks;
    // ...
}

class PDFFile {
public:
    PDFFile(QString file_path);
    ~PDFFile() = default;
    // ...
private:
    std::vector<PDFPage> pages;
    // ...
}

每次打开新的PDF文件,就会将保存PDF文件的PDFFile指针指向新的文件。

问题

上述实现貌似没什么问题,但当多次打开PDF文件时,内存占用会快速增加,每打开一个新的PDF文件,都会增加一部分内存占用,直至软件被操作系统kill。

假设为了PDF页面展示的清晰度,转化时做了放大,导致QImage占用的内存比较大。那么内存占用一直增大的原因是什么呢?

C++中常见的内存管理方法

上面代码的问题处在PDFPage的析构函数上,PDFPage用指针指向QImage,但在析构函数中并没有主动释放图片占用的大块内存,这就导致了内存泄漏,也就是程序内存一直增加直至crash。

修改PDFPage的析构函数如下,就能解决内存泄露的问题:

~PDFPage() {
    delete img;
    for (auto mark : marks) {
        delete mark;
    }
}

虽然上述析构函数能够解决内存泄漏的问题,但如果实现比较复杂,很有可能导致其他问题

比如imgowner不够明晰,出现多次对imgdelete,就可能导致crash。这也是为什么用c++实现的大型项目,内存管理是一个十分让人头疼的问题。针对每个指针,都要明晰它的owner并在不再使用时delete释放内存,小心再小心。

智能指针的出现给开发者带来了福音,用智能指针替换普通指针,开发者就不再需要手动释放内存了,也就不用担心忘记释放导致的内存泄漏,或者多次释放导致的crash问题了

PDFPage修改为使用智能指针,就能同时解决内存泄漏和可能存在的闪退问题

class PDFPage {
public:
    PDFPage(std::shared_ptr<QImage> _img);
    ~PDFPage() = default;
    void paint();
    void addMark(std::shared_ptr<Mark> mark);
    // ...
private:
    std::shared_ptr<QImage> img;
    std::vector<std::shared_ptr<Mark>> marks;
    // ...
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值