【问题标题】:Unable to figure out memory leak in my code无法找出我的代码中的内存泄漏
【发布时间】:2019-03-13 18:37:43
【问题描述】:

我已经编写了以下代码并且它工作正常,但是当我运行 valgrind 来检查泄漏时,我得到了一个很大的泄漏。不知道我做错了什么。

请任何人帮助我理解我做错了什么?

我的单身班:

头文件:SampleClass.h

#ifndef SAMPLECLASS_H
#define SAMPLECLASS_H

    struct sqlite3;

    class SampleClass
    {
        private:
        static SampleClass *m_pHandle;
        sqlite3 *m_pSqlDb;

        public:
        static SampleClass* getHandle() { 
            if (!m_pHandle)
            {
                m_pHandle = new SampleClass();
            } 
            return m_pHandle; 
        }

        static void deleteHandle()
        {
            delete m_pHandle;
            m_pHandle = nullptr;
        }
        void setDatabase(const sqlite3 *psqldb)
        {
            if (psqldb)
            {
            m_pSqlDb = const_cast<sqlite3*>(psqldb);
            }
            else { 
                // print error 
            }
        }

        private:
        SampleClass() : m_pSqlDb(nullptr) {}
        ~SampleClass() { m_pSqlDb = nullptr; }

        SampleClass(const SampleClass&) = delete;
        SampleClass& operator=(const SampleClass&) = delete;
        SampleClass(SampleClass&&) = delete;
        SampleClass& operator=(SampleClass&&) = delete;

    };

    #endif // SAMPLECLASS_H

实现:SampleClass.cpp

#include "SampleClass.h"

    SampleClass* SampleClass::m_pHandle = nullptr;

我的驱动程序:Test.cpp

#include "SampleClass.h"
#include <sqlite3.h>

int main()
{
    sqlite3 *mydb;
    const int retStatus = sqlite3_open_v2("./CPMDB_M100.db", &mydb, SQLITE_OPEN_READWRITE, nullptr);

    SampleClass::getHandle()->setDatabase(mydb);

    SampleClass::deleteHandle();

    return 0;
}

在我的实际实现中,我得到了如下所示的泄漏摘要。

> LEAK SUMMARY:
> ==32074==    definitely lost: 0 bytes in 0 blocks
> ==32074==    indirectly lost: 0 bytes in 0 blocks
> ==32074==      possibly lost: 0 bytes in 0 blocks
> ==32074==    still reachable: 82,680 bytes in 75 blocks
> ==32074==                       of which reachable via heuristic:
> ==32074==                         length64           : 9,968 bytes in 73 blocks

如果我删除 main() 中的 deleteHandle() 调用,那么所有丢失的块字节都会归入“仍然可访问”类别。

LEAK SUMMARY:
==32095==    definitely lost: 872 bytes in 1 blocks
==32095==    indirectly lost: 9,016 bytes in 71 blocks
==32095==      possibly lost: 0 bytes in 0 blocks
==32095==    still reachable: 72,784 bytes in 2 blocks
==32095==                       of which reachable via heuristic:
==32095==                         length64           : 80 bytes in 1 blocks

要编译的命令:

g++ -c -std=gnu++11 Test.cpp
g++ -c -std=gnu++11 SampleClass.cpp
g++ -o Test Test.o SampleClass.o -L/usr/include -lsqlite3

谢谢

【问题讨论】:

  • 你的 deleteHandle() 函数不应该将句柄设置为 null 然后删除它吗?
  • 那么他肯定有内存泄漏。您是否尝试将指向数据库的指针设为空?
  • 什么是m_pHandle?你是说m_handle 吗?向我们展示您正在编译的实际源代码。
  • OK 删除 cmets 并建议您熟悉并开始观察 RAII。在你这样做之前,你注定要摸索出劣质的解决方案。
  • @SharpIncTechAndProgramming 如果您首先将处理程序设置为空,那么您将丢失要调用删除的内存地址。所以当前的顺序是正确的,不是你建议的。

标签: c++ pointers memory-leaks singleton valgrind


【解决方案1】:

您没有使用sqlite3_close_v2 关闭 SQL 数据库。

【讨论】:

  • 我忘了添加它,但实际代码有这个但仍然没有工作。我已经弄清楚了真正的原因。谢谢
猜你喜欢
  • 1970-01-01
  • 2021-08-14
  • 1970-01-01
  • 2014-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多