【发布时间】: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 结构本身?