内存泄漏!我该如何修复它?

3
好的,所以我刚开始学习关于内存泄漏的知识。我运行了Valgrind来查找内存泄漏。我得到了以下结果:
==6134== 24 bytes in 3 blocks are definitely lost in loss record 4 of 4
==6134==    at 0x4026351: operator new(unsigned int) (vg_replace_malloc.c:255)
==6134==    by 0x8048B74: readInput(char&) (in calc)

那是否明确意味着泄漏问题出现在我的readInput函数中?如果是的话,我该如何消除内存泄漏呢?以下是有问题的函数代码:
double* readInput(char& command){
    std::string in;
    std::getline(std::cin, in);

    if(!isNumber(in)){
        if(in.length()>1){
            command = 0;
        }
        else{
            command = in.c_str()[0];
        }
        return NULL;
    }
    else{
        return new double(atof(in.c_str()));
    }
}
3个回答

11

使用:

// ...
   return new double(atof(in.c_str()));
// ...

new 从自由存储区获取一个资源,该资源正在被返回。为了避免内存泄漏,必须使用 delete 来释放返回的值。


如果您正在一个while循环中调用该函数,number在下一次运行循环之前应该被使用delete释放。只使用一次delete将只释放最后一个获取的资源。
// ....

while( condition1 )
{
     double *number = NULL ;
     number = readInput(command) ;

     if( condition2 )
     { .... }
     else
     { .... }

     delete number ;  // Should be done inside the loop itself.
                      // readInput either returns NULL or a valid memory location.
                      // delete can be called on a NULL pointer.
}

好的...我明白了。在我的主函数中,我声明了“double* number = NULL”。在一个while循环内,我调用“number = readInput(command);”,然后根据'number'的值进行if/else语句。我认为如果不删除'number',会导致不良结果,对吗?但是不删除它将导致每次循环时都会出现内存泄漏,对吗?谢谢! - user618712
不对... 我刚刚在我的 main() 函数中尝试添加了 "delete number;" 语句,但它并没有破坏程序或清除内存泄漏。 - user618712

3
你正在返回一个new double...它何时被释放?你确实会在某个时候调用delete...对吧?
个人建议只返回非零表示成功,零表示失败,并将值放入double *(或double &)参数中。这样你根本不需要使用new

2
你返回一个新分配的double。你是否在某个地方删除它?
为什么返回指向新分配的double的指针?为什么不只返回一个double呢?返回一个8字节的临时值并不是什么大问题,调用者可以决定如何处理它(包括在堆上分配一个新的double)。假设这些值不是很大,我更愿意返回一个临时的double。将new与实际使用更接近使内存管理变得更容易。
此外,分配大量非常小的块可能会导致堆使用效率低下和堆碎片化,因此程序可能会在原本不会出现问题的情况下耗尽内存,并且即使看起来还有很多剩余内存,也可能无法分配大块内存。这可能重要,也可能不重要(特别是在运行时间可能被I/O主导的函数中,需要额外的内存分配时间可能重要,也可能不重要)。这可能是微观优化,但如果没有使用小的分配的充分理由,最好养成不使用它们的习惯。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接