微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C纯虚方法内存管理问题

我有一个基类(这里是AClass),它有一个受保护的资源(此处为str),它在AClass析构函数中被释放.派生的BClass具有纯虚拟Init方法.派生的cclass实现了Init,它为受保护的资源分配了一些内存.

Valgrind说我有3个分配和2个释放.老实说,我只明确地看到1个alloc和1个free,但我会接受有一些我看不到的(现在,但请有人解释).但是,为什么他们至少不平衡?每个派生的实例是否也拥有它自己的str并且它没有被释放?

#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,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的实例时,str指针首先从AClass认构造函数中分配一个来自malloc调用的指针,然后在cclass :: Init中分配一个来自malloc调用的指针.从不释放在AClass认构造函数中分配的内存,并且当在cclass :: Init中覆盖str时指针会丢失.

您可以在strlass指针中检查非NULL值,然后在cclass :: Init中重新分配它.或者,您可以将str赋值封装在执行此检查的成员函数中,以便在其他地方不会出现此问题:

void allocate_str(int size) {
   if (str) free(str);
   str = (char*) malloc(size * sizeof(char));
}

更好的是,您可以利用C运行时库的许多现代功能,包括字符串对象和智能指针.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐