c++纯虚拟方法内存管理问题
C++ pure virtual method memory management question
我有一个基类(这里的AClass
),它有一个protected
资源(这里的str
),它在AClass
析构函数中获得free
'd。派生的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 %sn", 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)
当你先构造CClass
的实例,然后再构造Init
时,str
指针首先被分配一个来自AClass
默认构造函数中malloc
调用的指针,然后在CClass::Init
中分配一个来自malloc
调用的指针。AClass
默认构造函数中分配的内存永远不会被释放,并且当str
在CClass::Init
中被覆盖时,指针将丢失。
在CClass::Init
中重新赋值之前,可以检查str
指针中的非null值。或者,您可以将str
赋值封装在执行此检查的成员函数中,这样就不会在其他地方出现这种问题:
void allocate_str(int size) {
if (str) free(str);
str = (char*) malloc(size * sizeof(char));
}
更好的是,您可以利用c++运行时库的许多现代特性,包括字符串对象和智能指针。
这与虚函数没有任何关系。Valgrind检测的三个分配是:
-
new CClass
inmain
. -
malloc
inAClass
constructor. -
malloc
inCClass::Init
.
至于为什么调用不平衡:你正在泄漏str
,在AClass
构造器中分配-你正在改变CClass::Init
中的str
指针:
void Init() {
// ...
str = (char *) malloc(255 * sizeof(char));
// ...
};
AClass的默认构造函数有这样一行:
str = (char *) malloc(5 * sizeof(char)); // hey, 5 bytes!
在你的Init中,当你这样做的时候,你失去了它
str = (char *) malloc(255 * sizeof(char));
第三个alloc(第二个free)是CClass
相关文章:
- 字符 * 未从重载运算符或内存管理问题正确返回
- Waveshare 电子纸 ESP32 板上的 HTTP 客户端管理问题
- c++中的内存管理问题
- C++堆栈内存管理问题
- C 内存管理问题,std :: vector nevere rase内存超出范围
- MPI 新手 - 关于'mpirun'如何工作和流程管理的一些问题
- 内存管理策略的问题
- C++中的复杂内存管理问题
- 有关资源管理器类的 RAII 问题
- CUDA 内存管理/类问题中的指针
- 执行命令行管理程序命令时出现性能问题
- 在 Qt5.3(mingw32) 中删除 QQuickView 的内存管理问题
- C++内存管理问题(分配大量内存,但从不释放内存)
- 内存管理容器设计问题 - 项目需要继承
- C++中管理内存泄漏的问题
- 在头文件中存储代码会导致c++中的内存管理问题吗?
- 内存管理问题
- 涉及类析构函数和删除运算符的一些内存管理问题
- CPP中字符串的内存管理问题
- c++纯虚拟方法内存管理问题