【发布时间】:2011-04-09 20:19:50
【问题描述】:
我有一个基类(这里是AClass),它有一个protected 资源(这里是str),它在AClass 析构函数中得到free。派生的BClass 有一个纯虚拟的Init 方法。派生的CClass 实现了Init,它为受保护的资源分配了一些内存。
Valgrind 说我有 3 个分配和 2 个释放。老实说,我只明确看到 1 个 alloc 和 1 个 free,但我会接受有些我看不到(目前,但请有人解释)。但是,为什么它们至少不平衡?每个派生实例是否也有自己的 str 并且没有得到 free'd?
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
class AClass;
class BClass;
class CClass;
class AClass
{
public:
AClass() : str(NULL) {
printf("AClass Constructor with no params.\n");
str = (char *) malloc(5 * sizeof(char));
}
AClass(char *foo) {
printf("AClass Constructor with params, %s.\n", foo);
}
virtual ~AClass () {
printf("AClass Destructor. Getting ready to free %s\n", str);
free(str);
printf("\tfree.\n");
}
protected:
char *str;
};
class BClass : public AClass
{
public:
BClass() {
printf("BClass Constructor with no params.\n");
};
BClass(char *foo) : AClass(foo) {
printf("BClass Constructor with params, %s.\n", foo);
str = foo;
};
virtual void Init() = 0;
virtual ~BClass () {
printf("BClass Destructor.\n");
};
};
class CClass : public BClass
{
public:
CClass () {
printf("CClass Constructor with no params.\n");
};
void Init() {
printf("CClass Init method.\n");
str = (char *) malloc(255 * sizeof(char));
printf("\tmalloc.\n");
snprintf(str, 255 * sizeof(char), "Hello, world.");
};
virtual ~CClass () {
printf("CClass Destructor.\n");
};
};
int main (int argc, char const *argv[])
{
printf("Start.\n");
BClass *x = new CClass();
x->Init();
delete x;
printf("End.\n");
return 0;
}
这是 Valgrind 的输出。
==6641== Memcheck, a memory error detector
==6641== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==6641== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==6641== Command: ./a.out
==6641==
Start.
AClass Constructor with no params.
BClass Constructor with no params.
CClass Constructor with no params.
CClass Init method.
malloc.
CClass Destructor.
BClass Destructor.
AClass Destructor. Getting ready to free Hello, world.
free.
End.
==6641==
==6641== HEAP SUMMARY:
==6641== in use at exit: 5 bytes in 1 blocks
==6641== total heap usage: 3 allocs, 2 frees, 268 bytes allocated
==6641==
==6641== LEAK SUMMARY:
==6641== definitely lost: 5 bytes in 1 blocks
==6641== indirectly lost: 0 bytes in 0 blocks
==6641== possibly lost: 0 bytes in 0 blocks
==6641== still reachable: 0 bytes in 0 blocks
==6641== suppressed: 0 bytes in 0 blocks
==6641== Rerun with --leak-check=full to see details of leaked memory
==6641==
==6641== For counts of detected and suppressed errors, rerun with: -v
==6641== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 18 from 7)
【问题讨论】:
-
当你打开
--leak-check=full选项时会发生什么? -
有点不相关,但是您使用 char* 而不是 std::string 有什么原因吗?
-
AClass的构造函数中有一个malloc。你为什么不为那个malloc做printf("\tmalloc.\n")呢?这就是您在程序输出中看不到不平衡的malloc的原因。 -
另外,当您的整个程序中只有一个类实例时,您所说的“每个派生实例”是什么?
-
@MahlerFive,对 C++ 有点陌生,周围没有任何其他 C++ 开发人员,我求助于 Google 的 C++ 样式指南 (bit.ly/eMAtAy)。我也对他们对此的呼吁表示怀疑,如果您愿意,我很乐意在不同的论坛上讨论它。
标签: c++ inheritance memory-leaks valgrind