【问题标题】:Tracking down Valgrind 40 bytes in 1 blocks are definitely lost in loss record在丢失记录中跟踪 Valgrind 1 个块中的 40 个字节肯定会丢失
【发布时间】:2012-02-15 19:47:19
【问题描述】:

我是 Valgrind 的新手(我的 C/C++ 生锈了),我收到一个错误:

40 bytes in 1 blocks are definitely lost in loss record 35 of 111
==26930==    at 0x4C275C2: operator new(unsigned long) (vg_replace_malloc.c:261)
==26930==    by 0x5EFAFDB: cassie_init_with_timeout (cassie.cc:49)
==26930==    by 0x46E647: ngx_cassandra_upstream_get_peer (ngx_cassandra_upstream.c:274)
==26930==    by 0x41E00B: ngx_event_connect_peer (ngx_event_connect.c:25)

我猜 char *last_error_string 让我很受打击,但我该如何追踪呢?

这是我的来源:

Cassie 对象的创建:

cassie_t cassie;

char *error = NULL;
cassie = new Cassie(host,port,error,CASSIE_ERROR_NONE);  /* this is line 49 in the above valgrind trace */
cassie->cassandra               = cassandra;

cassie_t 是一个对象的结构。

typedef struct Cassie *cassie_t;

我有这个是因为我包装了一个 C++ 库以便从 C 中调用它。

这是我们的对象 cassie_private.h

#include <string>
#include "libcassandra/cassandra.h"
#include "libcassie/cassie.h"

#ifdef __cplusplus
namespace libcassie {
    using namespace std;
    using namespace boost;
    class Cassie
    {
      // TODO do we need the host and the port??
      public:
            const char*     host;
        int             port;
        cassie_error_code_t last_error_code;
        char*           last_error_string; /* I am guessing my memory problem is here */
        tr1::shared_ptr<libcassandra::Cassandra>                    cassandra;

        Cassie();
        Cassie(const char *&host, int &port,char* &in_error_str, cassie_error_code_t error);
        ~Cassie();
    };
#else
    typedef
         struct Cassie
           Cassie; /* this is for in C */
#endif

}

#endif

这里是 cassie_private.cc

#include "cassie_private.h"

namespace libcassie {

using namespace std;
using namespace libcassandra;

Cassie::Cassie() :
    host(),
    port(0),
    last_error_code(),
    last_error_string(NULL),
    cassandra()
{}

Cassie::Cassie(const char * &in_host, int &in_port, char* &in_error_str, cassie_error_code_t error) :
        host(in_host),
        port(in_port),
        last_error_code(error),
        last_error_string(in_error_str),
        cassandra()
{}

Cassie::~Cassie() {
    if(last_error_string) delete last_error_string;
}

}

调用它是为了在使用结束时删除对象:

void cassie_free(cassie_t cassie) {

    if(!cassie) return;
    cassie->~Cassie();
    if(cassie) delete cassie;

}

如何跟踪此内存泄漏?

【问题讨论】:

  • cassie.cc 第 49 行是什么? Valgrind 似乎认为您正在调用 new,然后没有在所述对象上调用 delete
  • @Dan:比那更糟; Valgrind 消息意味着 OP 正在调用 new,然后在某个时候丢弃指针。
  • @OliCharlesworth:是的,这更正确。尽管原因通常是让指针离开作用域或在您不再需要它时被覆盖,所以您应该在某个时候释放它。 :)
  • cassie_free 函数看起来很可疑。为什么要手动调用析构函数,然后调用delete?为什么要对NULL 进行冗余检查?此外,在 typedef 后面隐藏指针通常被认为是不好的做法,因为它会使生成的代码难以阅读。
  • 正如我提到的,我的 C/C++ 生锈得要命。在这种情况下,我如何不使用 typedef ?使用 Cassie 结构本身?

标签: c++ valgrind


【解决方案1】:

Valgrind 消息意味着您已经分配了一些内存(在 cassie.cc 的第 49 行),但是您正在丢失/覆盖指针,而没有在其上调用 delete

您应该跟踪该指针值的去向(在调试器中或通过检查),以便发现它丢失的位置。您可能会考虑在指针上放置一个调试器观察点;这将在它被覆盖的情况下识别问题。如果您要在调试器中执行此操作,请确保您已在未启用优化的情况下进行编译。

【讨论】:

  • 我怎样才能隔离 valgrind 是在抱怨哪个指针?是 char* 错误吗?
  • @chrislovecnm:它告诉你查看 cassie.cc 的第 49 行。遵循new 在该行返回的值。
  • 对不起,如果我很密集。但特别是指向 cassie_t 的指针,而不是被击中的指针。
  • @chrislovecnm:我不确定你的意思。从您的代码 sn-p 中,我现在可以看到您正在将 new 的结果分配给名为 cassie 的指针。下一步要去哪里?
  • 我想我需要清理没有 typedef 的代码,并从那里跟踪它。这是一些没有很好地外部化到 C 代码中的开源代码。
猜你喜欢
  • 1970-01-01
  • 2021-04-21
  • 2016-06-30
  • 1970-01-01
  • 2021-03-17
  • 1970-01-01
  • 2021-11-02
  • 1970-01-01
  • 2011-07-26
相关资源
最近更新 更多