可能的内存泄漏?

时间:2009-02-20 06:51:47

标签: c++ inheritance pointers memory-leaks class

好的,所以我有两个类,在代码中按顺序称它们为A和B。 B类将A类实例化为数组,B类也有一个错误消息char *变量,A类必须在发生错误时设置。我创建了一个带有纯虚函数的第三个类,用于在B中设置errorMessage变量,然后使B成为该第三个类的子元素。 A类创建一个指向第三个类的指针,称之为C - 当B初始化A对象的数组时,它循环遍历它们并调用A中的函数将A的指针设置为C--它将“this”传递给该函数,然后A将指针C设置为“this”,并且因为C是B的父级,A可以设置C-> errorMessage(我必须完成所有这些,因为A和B不能同时在彼此之间知道编译时间。)

无论如何它工作正常,但是当我将命令行参数传递给main(int,char **)时,除非我将七个,八个或十二个以上的参数传递给它,否则它会工作...我把它缩小了(通过注释掉行)代码行,在A中,将指针设置为C,指向由B传递给它的值。这对我没有意义......我怀疑是内存泄漏或其他什么,但它似乎是错的,我不知道如何解决它...而且我不明白为什么特别是七,八,十二个以上的论点不起作用,1-6和9-12工作正常。

这是我的代码(剥离) -

//class C
class errorContainer{

public:
    virtual ~errorContainer(){ }
    virtual void reportError(int,char*)=0;

};

//Class A
class switchObject{
    void reportError(int,char*);
    errorContainer* errorReference;

public:
    void bindErrorContainer(errorContainer*);
};

//Class A member function definitions
void switchObject::reportError(int errorCode,char* errorMessage){
    errorReference->reportError(errorCode,errorMessage);
}

void switchObject::bindErrorContainer(errorContainer* newReference){
    errorReference=newReference; //commenting out this line fixes the problem
}

//Class B
class switchSystem: public errorContainer{
    int errorCode;
    char* errorMessage;

public:
    switchSystem(int); //MUST specify number of switches in this system.
    void reportError(int,char*);
    int errCode();
    char* errMessage();
    switchObject* switchList;
};

//Class B member function definitions
switchSystem::switchSystem(int swLimit){
    int i;
    switchList=new (nothrow) switchObject[swLimit];
    for(i=0;i<swLimit;i++){
        switchList[i].bindErrorContainer(this);
    }
    errorCode=0;
    errorMessage="No errors.";
}

void switchSystem::reportError(int reportErrorCode,char* reportErrorMessage){
    int len=0,i;    
    errorCode=reportErrorCode;
    if(errorMessage){
        delete[] errorMessage;
    }
    while(reportErrorMessage[len]!='\0'){
        len++;
    }
    errorMessage=new char[len];
    for(i=0;i<=len;i++){
        errorMessage[i]=reportErrorMessage[i];
    }   
}

int switchSystem::errCode(){
    return errorCode;   
}

char* switchSystem::errMessage(){
    return errorMessage;    
}

任何人都知道我在这里做错了什么? 它正在惹恼我...我似乎无法修复它。

--- --- EDIT 好吧,我已经设置了我这样做的方式,我可以在main()

中使用它
int main(int argc,char** argv){
   switchSystem sw (2)
   sw.switchList[0].argumentCount=2;
   sw.switchList[1].argumentCount=0;
   sw.switchList[0].identifier="a";
   sw.switchList[1].identifier="switch";
   sw.init(argc,argv);
   if(sw.errCode()>0){
      cout<< "Error "<< sw.errCode()<< ": "<< sw.errMessage()<< endl;
   }
}

这个程序应该读取命令行参数并处理用户定义的“开关” - 就像大多数命令行程序如何处理开关一样,而不是在main的开头测试所有这些,我想尝试写一个类和一些函数为我做 - 创建一个switchSystem对象,其中包含开关数,设置它们的标识符,它们是否接受参数,然后将命令行参数传递给“init()”以对其进行排序。然后进行测试,

if(sw.isSet("switch")){ ... }

4 个答案:

答案 0 :(得分:5)

你似乎很可怕:

  • 将动态内存与静态字符串常量(“无错误。”)混合在同一指针中。
  • 使用显式while - 循环来计算字符串的长度;你没听说过strlen()吗?
  • 使用这种低级C类字符串处理,没有充分理由...... std::string出了什么问题?
  • 在为字符串分配空间并复制时,不能正确解释字符串中的终止'\ 0'。长度也未存储,导致生成的char数组难以解释。

答案 1 :(得分:4)

  • reportError()应在switchSystem中声明为虚拟,与errorContainer中一样。
  • char*应该是std::string,以避免所有不必要的工作。
  • 是否有某些原因导致您无法使用std::vector<switchObject>代替new[]
  • 当它指向静态文字字符串时,您不应该delete[] errorMessage。这导致未定义的行为。 (翻译:Bad Thing(TM)。)
  • 为什么要迭代计算和复制char*的内容?这是在乞求麻烦。你没有做任何事情来保护自己免受伤害。
  • 为什么switchObject必须将字符串传递给switchSystem?简单地返回错误代码或throwstd::exception派生的某个类不是更好吗?或者它应该将字符串发送到全局日志记录工具?

我想也许你应该重新考虑你的设计,而不是试图解决这个问题。

答案 2 :(得分:2)

以上所有消息都包含非常好的建议,除非这是家庭作业,你不能使用STL我建议你遵循它们,你的问题会少得多。

例如,在此代码段中

errorMessage=new char[len];
for(i=0;i<=len;i++){
  errorMessage[i]=reportErrorMessage[i];
}

你已经分配了len个字节,但你正在写入len + 1个字节,你没有为空终结符'\ 0'分配内存,覆盖内存会导致难以追踪的令人讨厌的错误。

答案 3 :(得分:0)

我认为内存泄漏是你在这里的次要问题。您最好抛出此代码,然后使用新方法重新开始。这是一团糟。