如何阻止指针内存泄漏? 我在C++方面很好,但是在指针和内存方面我一直很差。我陷入了这种情况,我不知道是否有解决办法 typedef unsigned long long ullong; class MathClass { //This is just an example class public: MathClass() {num = new ullong[1]();} MathClass operator+(MathClass b) { //This is not my actual function, just one that has the same problem MathClass c; c.num[0] = num[0] + b.num[0]; delete [] num; num = NULL; return c; } public: ullong* num; };

如何阻止指针内存泄漏? 我在C++方面很好,但是在指针和内存方面我一直很差。我陷入了这种情况,我不知道是否有解决办法 typedef unsigned long long ullong; class MathClass { //This is just an example class public: MathClass() {num = new ullong[1]();} MathClass operator+(MathClass b) { //This is not my actual function, just one that has the same problem MathClass c; c.num[0] = num[0] + b.num[0]; delete [] num; num = NULL; return c; } public: ullong* num; };,c++,pointers,memory-leaks,C++,Pointers,Memory Leaks,在这种情况下,这是可行的 MathClass a; MathClass b; for (int i = 0; i < 1000; i++) { a = a + b; } 因为我将a设置为等于a+b,所以当+函数运行时,它会将a设置为等于c并删除旧的a num 对于这样的情况,它会导致一个错误,因为我正在删除b的num MathClass a; MathClass b; MathClass c; for (int i = 0; i < 1000; i++) { a =

在这种情况下,这是可行的

MathClass a;
MathClass b;
for (int i = 0; i < 1000; i++) {
    a = a + b;
}
因为我将a设置为等于a+b,所以当+函数运行时,它会将a设置为等于c并删除旧的a num

对于这样的情况,它会导致一个错误,因为我正在删除b的num

MathClass a;
MathClass b;
MathClass c;
for (int i = 0; i < 1000; i++) {
    a = b + c;
}

如果我不删除num,这将起作用,但会导致内存泄漏。当我不删除num时,它的内存很容易超过100MB。我确信答案很简单,但我想不出来。

你需要三五法则

当您分配内存时,或者如果您需要实现赋值、析构函数或复制构造函数,那么您需要所有三个五移动构造函数和移动赋值

当用新的SEND SyrdYPPTR分配内存时,您需要控制复制分配和删除工作。

class MathClass { //This is just an example class
public:
    MathClass() {num = new ullong[1]();}
    ~MathClass() { delete [] num;} // cleans up memory.
    MathClass( const MathClass & rhs ) { num = new ullong[1](); num[0] = rhs.num[0]; }
    MathClass& operator=( const MathClass & rhs )
    {
       if( &rhs != this ) {
          num[0] = rhs.num[0];
       }
       return *this;
    }

    MathClass operator+(MathClass b) { //This is not my actual function, just one that has the same problem
    MathClass c;
    c.num[0] = num[0] + b.num[0];
    // the wrong place delete [] num;
    num = NULL;
    return c;
    }
public:
    ullong* num;
};

运算符+中的delete[]位于错误的位置,因为它试图找到释放内存的正确位置。然而,让所有操作正常工作的最简单方法是应用,并确保内存在构造时构造,在删除时删除,赋值和移动操作符正确工作。实际上,问题不完全在于指针,而在于操作符重载和类实现,正如注释中提到的那样。 如果在第一个示例中更改参数顺序,即a=a+b->a=b+a,您将看到与第二个示例相同的错误。因此,这里有一篇关于实施的好文章 代码可能是这样的

#include <iostream>
#include <algorithm>

typedef unsigned long long ullong;

class MathClass {

public:
    MathClass() { num = new ullong[ 1 ](); }
    MathClass( const MathClass &a ) { 
        *this = a;
    }
    ~MathClass() {  
        delete[] num;
        num = NULL;
    }

    MathClass &operator=( const MathClass &a ) {
        if ( this != &a ) {
            num = NULL;
            num = new ullong[ 1 ];
        }
        std::copy( a.num, a.num + 1, num );

        return *this;
    }

    friend MathClass operator+( const MathClass &a, const MathClass b ) {
        MathClass c;
        c.num[ 0 ] = a.num[ 0 ] + b.num[ 0 ];

        return c;

    }
ullong *num;
};

int main( int argc, char **argv ) {
   MathClass a;
   MathClass b;
   MathClass c;
   for ( int i = 0; i < 1000; ++i ) {
      std::cout << "a.num[ 0 ] is " << a.num[ 0 ] << std::endl;
      std::cout << "b.num[ 0 ] is " << b.num[ 0 ] << std::endl;
      a = b + a;
      a = c + b;
   }

   return 0;
}
在main std::cout中,仅用于输出可见性。复制构造函数的实现当然比我的要好得多,但这里的关键点是,当您使用coplex类型时,您几乎总是必须重新实现copy并分配操作符,因为如果不总是调用它们,它们通常都是这样。
关于您的代码,还有其他一些值得一提的时刻。至少自从C++11null更改为nullptr之后,typedef也就不那么常见了。使用引用而不是指针,这是一种很好的做法,尤其是在复杂参数的情况下,通过引用而不是通过值来传递它们,因为在通过值传递的情况下,将调用复制构造函数,并且您将不得不调用同一参数的实例,这可能导致内存过度使用

无关:typedef无符号long-long-ullong;总是让我想泡茶是有原因的。你为什么要用指针和动态分配来处理像整数这样的琐事?这确实增加了难度。你没有表现出来的唯一原因是你泄露了内存。总是喜欢用智能指针来处理原始的新的/Delphi——这些几乎不应该在现代C++中使用。除了析构函数,为什么你会有删除的地方?在我的实际项目中,我用指针作为数组。这只是一个具有相同问题的简单类。在这个MathClass中,我本可以只使用常规的无符号long long,但这不是我使用的;,num只存在几纳秒。取消它是没有意义的。而不是将复制构造函数基于运算符=,在复制构造函数上考虑Buffor运算符=。这允许您在需要时利用。同意析构函数中num的存在时间,但将NULL指定给它实际上还有另一个原因。如果任何人都可以访问这个内存地址,我们就不会有我们的值了,只有NULLand感谢,而不是基于操作符=上的复制构造函数,在复制构造函数上考虑Buffor操作符=。这允许您在需要时利用复制和交换习惯用法。这是一个有趣的想法我会给你额外的安全作为一个很好的理由。可能值得在删除前清空num的内容。还建议在删除后将指针设置为NULL,以避免多次删除导致未定义的行为,NULL指针是一种特殊情况。当然,在这种情况下,析构函数将被调用一次,指针将被删除一次。