以下代码肯定可以运行。我的问题是我在类函数中分配了一些内存并返回指向它的指针。但是在main函数中,我构建了一个新对象并为其指定了指针。但是如何释放返回的指针?我需要手动完成吗?
#include "stdio.h"
class Complex{
private:
float real;
float imaginary;
public:
Complex(float, float);
~Complex(void) {};
void set_real(float r);
void set_imaginary(float i);
float get_real();
float get_imaginary();
Complex* plus(Complex* another);
Complex* minus(Complex* another);
Complex* multiply(Complex* another);
};
Complex::Complex(float r, float i){
this->real = r;
this->imaginary = i;
}
void Complex::set_real(float r)
{this->real = r;}
void Complex::set_imaginary(float i)
{this->imaginary = i;}
float Complex::get_real()
{return real;}
float Complex::get_imaginary()
{return imaginary;}
Complex* Complex::plus(Complex* another){
Complex* result = new Complex(0,0);
result->set_real(this->real + another->real);
result->set_imaginary(this->imaginary + another->imaginary);
return result;
}
Complex* Complex::minus(Complex* another){
Complex* result = new Complex(0,0);
result->set_real(this->real - another->real);
result->set_imaginary(this->imaginary - another->imaginary);
return result;
}
Complex* Complex::multiply(Complex* another){
Complex* result = new Complex(0,0);
result->set_real((this->real * another->real) - (this->imaginary - another->imaginary));
result->set_imaginary((this->imaginary*another->real) + (this->real*another->imaginary));
return result;
}
int main(int argc, char* argv[]){
Complex* c = new Complex(3,4);
Complex* d = new Complex(6,9);
Complex* e = new Complex(0,0);
//will this line bring memory leak? Because all plus function already build a Complex object on leap. I don't know how to release it since I have to return it.
e = c->plus(d);
printf("result is %f + i%f", e->get_real(), e->get_imaginary());
delete c;
delete d;
delete e;
return 1;
}
答案 0 :(得分:6)
是的,你的代码就像疯了一样泄漏。如果您绝对需要通过指针返回,请返回std::unique_ptr<Complex>
,这样可以防止泄漏。但是你的代码不需要任何指针。
你可能想要的更像是这样:
Complex Complex::operator+(const Complex& another){ //pass by const reference
Complex result = Complex(0,0);
result.set_real(real + another.real);
result.set_imaginary(imaginary + another.imaginary);
return result;
}
或更简单:
Complex Complex::operator+(const Complex& another){
return Complex(real + another.real,
imaginary + another.imaginary);
}
在C ++中,我们通常通过“按值”或“通过const引用”传递和返回对象,并且不会对函数参数或返回使用大量指针。指针容易出错。通过值传递(并使用operator+
)允许:
int main() {
Complex c = Complex(3,4);
Complex d = Complex(6,9);
Complex e = Complex(0,0);
Complex e = a + b; //magic! no leaks!
printf("result is %f + i%f", e.get_real(), e.get_imaginary());
return 0;
}
关于无关的说明:
Complex::Complex(float r, float i)
:real(r) //faster for some types. This is "more correct"
,imaginary(i)
{}
float Complex::get_real() const //const since it doesn't change anything
{return real;}
最后,在main
中,return 0
表示“一切正常”并且返回任何其他值意味着“出了问题”
答案 1 :(得分:4)
Complex* e = new Complex(0,0); //will this line bring memory leak? Because all plus function already build a Complex object on leap. I don't know how to release it
因为我必须归还它。 e = c->加(d);
是的,它会泄漏。首先分配e
,然后重新分配它以指向函数返回的任何内容。现在,您首先分配的内存在空间中丢失,而不会被释放。你应该这样做:
Complex* e;
e = e->plus(d);
然后还有其他一些问题,例如,当你真的应该重载plus
和minus
时,为什么要创建operator+
和operator-
函数。
通过指针返回所有内容是愚蠢的。只是按价值回报。
答案 2 :(得分:4)
不要使用所有指针,只需返回值。
Complex* Complex::plus(Complex* another){
Complex* result = new Complex(0,0);
result->set_real(this->real + another->real);
result->set_imaginary(this->imaginary + another->imaginary);
return result;
}
变为:
Complex Complex::plus(const Complex& another){
Complex result(0,0);
result.set_real(real + another.real);
result.set_imaginary(imaginary + another.imaginary);
return result;
}
答案 3 :(得分:1)
由于你的类只包含两个浮点数,我倾向于建议不要使用指针(即只返回一个Complex
)。
这只是8个字节(至少在我的系统上),它与指针的大小相同(至少在我的系统上)。
答案 4 :(得分:1)
删除所有堆分配,即根本不使用new。
变换:
Complex* Complex::plus(Complex* another){
Complex* result = new Complex(0,0);
result->set_real(this->real + another->real);
result->set_imaginary(this->imaginary + another->imaginary);
return result;
}
成:
Complex Complex::plus(const Complex& another) const{
Complex result(0,0);
result.set_real(this.real + another.real);
result.set_imaginary(this.imaginary + another.imaginary);
return result;
}
答案 5 :(得分:1)
e = c->plus(d);
将导致泄漏,因为在指向新Complex的新指针之前,e指向的Complex未被释放。
尽管如此,STL还是有template <typename T> class complex;
#include <complex>
您可以为算术返回值实现成员函数:
Complex Complex::plus(const Complex& another)const{
Complex result(0,0);
result.set_real(this->real + another.real);
result.set_imaginary(this->imaginary + another.imaginary);
return result;
}
答案 6 :(得分:0)
一种方法是使用auto_ptr或类似的智能ptr。
或者,您也可以在加号或减号方法中传递对结果对象的引用,而不是需要分配的指针。换句话说,处理类模块外的内存。
答案 7 :(得分:0)
(一个?)问题是你正在分配一个'e'指针然后再将指针重新分配给add()的结果。在add函数中,它已经创建了一个要返回的新Complex对象。
所以要解决这个问题,主要的是你不应该提前分配E.
[或者您可以重新构建代码以使用复制/分配]