欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

28、使用valgrind 进行vector的内存检查

程序员文章站 2022-03-23 19:04:01
基本思想:最近做项目,遇到了在android上使用c++开发时,内存泄漏和内存释放失败的情况,顾复习一下之前的知识点,顺手也记录一下;提供一个demo和简单的分析叙述;#include#includeusing namespace std;typedef struct{ int x; int y;} Point;class Axis{ public:...

基本思想:最近做项目,遇到了在android上使用c++开发时,内存泄漏和内存释放失败的情况,顾复习一下之前的知识点,顺手也记录一下;

提供一个demo和简单的分析叙述;

#include<iostream>
#include<vector>
using namespace std;
typedef struct
{
        int x;
        int y;
} Point;


class Axis
{
        public:
                Axis()
                {}
                ~Axis()
                {
                        avpoint.clear();
                        vector<Point>().swap(avpoint);
                        cout << "after swap size:" << avpoint.size() << endl;
                        cout << "after swap capacity:" << avpoint.capacity() << endl;
                        for(int i=0;i<avpppoint.size();i++)
                        {
                                if(NULL!=avpppoint[i]){
                                        delete avpppoint[i];
                                         avpppoint[i]=NULL;
                                }
                        }
                        avpppoint.clear();
                        vector<Point*>().swap(avpppoint);

                        cout << "after swap size:" << avpppoint.size() << endl;
                        cout << "after swap capacity:" << avpppoint.capacity() << endl;

                }
        private:
                int x;
                int y;
                vector<Point> avpoint;
                vector<Point*> avpppoint;
        public:
                void setx(int x)
                {this->x=x;
                }
                void sety(int y)
                {this->y=y;
                }
                void init()
                {
                        Point pp;
                        pp.x=99;
                        pp.y=999;
                        avpoint.push_back(pp);
                        Point *vppoint=new Point();
                        vppoint->x=33;
                        vppoint->y=43;
                        avpppoint.push_back(vppoint);
                }
};

int main()
{
        vector<int> v;
        for(int i=0;i<72;i++)
        {
                v.push_back(i);
        }

        cout << "size:" << v.size() << endl;
        cout << "capacity:" << v.capacity() << endl;
        v.clear();
        vector<int>().swap(v);
        cout << "after swap size:" << v.size() << endl;
        cout << "after swap capacity:" << v.capacity() << endl;
        //////////////////////////////////////////////////////////////////////
        vector<Point> vp;
        Point point;
        for(int i=0;i<4;i++)
        {
                point.x=i;
                point.y=i;
                vp.push_back(point);
        }


        vp.clear();
        vector<Point>().swap(vp);
        cout << "size:" << vp.size() << endl;

        cout << "capacity:" << vp.capacity() << endl;
        ////////////////////////////////////////////////////////////////////////////////////
        vector<Axis*> vaxis;
        Axis *axis=new Axis();
        axis->setx(1);
        axis->sety(2);
        vaxis.push_back(axis);
        vaxis.clear();
        vector<Axis*>().swap(vaxis);
        delete axis;
        cout << "size:" << vaxis.size() << endl;
        cout << "capacity:" << vaxis.capacity() << endl;

        ////////////////////////////////////////////////////////////////////////////////////
        Axis *bxis=new Axis();
        bxis->init();
        delete bxis;




        return 0;
}

执行结果

ubuntu@ubuntu:~/test$ ./a.out
size:72
capacity:128
after swap size:0
after swap capacity:0
size:0
capacity:0
after swap size:0
after swap capacity:0
after swap size:0
after swap capacity:0
size:0
capacity:0
after swap size:0
after swap capacity:0
after swap size:0
after swap capacity:0

内存检查valgrind  (简单说明 我是用的gcc-5.4 valgrind 3-13 ; 编译器版本和内存检查工具不同 生成的valgrind的报告存在差异,差异在于是否输出内存池的的log信息,关于内存池的相关知识,请参考相关文档)

ubuntu@ubuntu:~/test$ G_SLICE=always-malloc G_DEBUG=gc-friendly valgrind --tool=memcheck --leak-check=full --leak-resolution=high --num-callers=20 --show-reachable=yes --log-file=a.log  ./a.out
size:72
capacity:128
after swap size:0
after swap capacity:0
size:0
capacity:0
after swap size:0
after swap capacity:0
after swap size:0
after swap capacity:0
size:0
capacity:0
after swap size:0
after swap capacity:0
after swap size:0
after swap capacity:0

内存检查的log

ubuntu@ubuntu:~/test$ cat a.log
==41010== Memcheck, a memory error detector
==41010== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==41010== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==41010== Command: ./a.out
==41010== Parent PID: 22172
==41010==
==41010==
==41010== HEAP SUMMARY:
==41010==     in use at exit: 72,704 bytes in 1 blocks
==41010==   total heap usage: 19 allocs, 18 frees, 74,948 bytes allocated
==41010==
==41010== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==41010==    at 0x4C2DBF6: malloc (vg_replace_malloc.c:299)
==41010==    by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==41010==    by 0x40106C9: call_init.part.0 (dl-init.c:72)
==41010==    by 0x40107DA: call_init (dl-init.c:30)
==41010==    by 0x40107DA: _dl_init (dl-init.c:120)
==41010==    by 0x4000C69: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==41010==
==41010== LEAK SUMMARY:
==41010==    definitely lost: 0 bytes in 0 blocks
==41010==    indirectly lost: 0 bytes in 0 blocks
==41010==      possibly lost: 0 bytes in 0 blocks
==41010==    still reachable: 72,704 bytes in 1 blocks
==41010==         suppressed: 0 bytes in 0 blocks
==41010==
==41010== For counts of detected and suppressed errors, rerun with: -v
==41010== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

其中这段信息的含义:

==41010== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==41010==    at 0x4C2DBF6: malloc (vg_replace_malloc.c:299)
==41010==    by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==41010==    by 0x40106C9: call_init.part.0 (dl-init.c:72)
==41010==    by 0x40107DA: call_init (dl-init.c:30)
==41010==    by 0x40107DA: _dl_init (dl-init.c:120)
==41010==    by 0x4000C69: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)

摘录他人的叙述:

“使用 Valgrind 分析 C++ 程序时,有一些问题需要留意。例如,这个程序并没有发生内存泄漏,但是从HEAP SUMMARY可以看到,程序分配了 2 次内存,但却只释放了 1 次内存,为什么会这样呢?

实际上这是由于 C++ 在分配内存时,为了提高效率,使用了它自己的内存池。当程序终止时,内存池的内存才会被操作系统回收,所以 Valgrind 会将这部分内存报告为 reachable 的,需要注意,reachable 的内存不代表内存泄漏,例如,从上面的输出中可以看到,有 72704 个字节是 reachable 的,但没有报告内存泄漏。”

本文地址:https://blog.csdn.net/sxj731533730/article/details/107552490

相关标签: C/C++基础知识