类代码中的内存泄漏 [英] memory leak in class code

查看:40
本文介绍了类代码中的内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好!


我在linux上使用gcc 3.2。

i有一个(自行开发的)矩阵类:


class cMatrix {//剥夺了必要的信息

....

double * data; //矩阵数据存储在堆数组中

cMatrix行(const int& r)const;

// const cMatrix& row(const int& r)const; // 这是否更好??为什么?

....

const double& dotproduct(const cMatrix& m1,const cMatrix& m2)const;

....

}


cMatrix cMatrix: :row(const int& r)const {

cMatrix * tmp = new cMatrix(1,ncols);

for(int i = 0; i< ncols; i ++ )(* tmp)[i] =数据[r * ncols + i];

返回* tmp;

}


const double& cMatrix :: dotproduct(const cMatrix& v1,const cMatrix& v2)

const {

double d = 0.0;

for(int i = 0; i< v1.elements(); i ++)d + = v1 [i] * v2 [i];

返回d;

}

int main(){


{

cMatrix m(10,10);

cMatrix r = m。第(1)行;

}


返回0;

}


使用valgrind我发现上面的main()泄漏了内存。


我的问题是:

*如何改变cMatrix :: row的代码避免内存泄漏?

*如何避免存储在堆栈中的对象以后被覆盖

当程序代码被进一步执行时?

*是有一个更好的语法(* tmp)[i] =" some value" ;?


附加信息:

*我后来肯定需要像

res = dotproduct(Ni,nodes.column(i)); (其中Ni也是矩阵)

正常工作。(^^^^^^^^^^^^^^^临时对象)

- >操作员和方法链接。


感谢任何帮助或想法!


-

flo

解决方案

" florian kno" < FL **** @ yahooQ.com>在消息中写道

新闻:lV ********************** @ news.chello.at ...

你好吧!

我在linux上使用gcc 3.2。
我有一个(自行开发的)矩阵类:

class cMatrix {/ /不需要的信息被剥夺
...
double * data; //矩阵数据存储在堆数组中

cMatrix行(const int& r)const;
// const cMatrix& row(const int& r)const; // 这是否更好??
为什么? ......
const double& dotproduct(const cMatrix& m1,const cMatrix& m2)
const; ...

cMatrix cMatrix :: row(const int& r)const {
cMatrix * tmp = new cMatrix(1,ncols);
for (int i = 0; i< ncols; i ++)(* tmp)[i] = data [r * ncols + i];
return * tmp;
}

const double& cMatrix :: dotproduct(const cMatrix& v1,const cMatrix&
v2)const {
double d = 0.0;
for(int i = 0; i< v1.elements(); i ++ )d + = v1 [i] * v2 [i];
返回d;
}

int main(){

{
cMatrix m(10,10);
cMatrix r = m.row(1);
}
返回0;
}
我的问题是:
*如何改变cMatrix :: row的代码以避免内存泄漏?


当你不需要时,不要使用''new''


cMatrix cMatrix :: row(const int& r)const

{

cMatrix tmp(1,ncols);

for(int i = 0; i< ncols; i ++ )

{

tmp [i] = data [r * ncols + i];

}

返回tmp;

}


在C ++中你不必使用''new'来实例化类对象。

*当程序代码被进一步执行时,如何避免存储在堆栈中的对象后来被覆盖?


我不明白这个问题???

*是否有更好的语法(* tmp)[i] =" some value" ;?


如果你没有使用我给你看的(未经测试的)代码中的指针,那么你就不会得到丑陋的语法。
附加信息:
*我后来肯定需要像
res = dotproduct(Ni,nodes.column(i)); (其中Ni也是矩阵)
正常工作。(^^^^^^^^^^^^^^^临时对象)
- >操作员和方法链接。




我在这里看不到你的问题。


-

Peter van Merkerk

peter.van.merkerk(at)dse.nl


你好!


Peter van Merkerk写道:

" florian kno" < FL **** @ yahooQ.com>在消息中写道
新闻:lV ********************** @ news.chello.at ...

我的问题是:
*如何改变cMatrix :: row的代码以避免内存泄漏?



Don''当你不必使用''new'时:

cMatrix cMatrix :: row(const int& r)const
{
cMatrix tmp(1, ncols);
for(int i = 0; i< ncols; i ++)
{
tmp [i] = data [r * ncols + i];
}
返回tmp;
}

在C ++中,你不必使用''new'来实例化类对象。




ok。

*当程序代码被进一步执行时,如何避免存储在堆栈中的对象后来被覆盖?



我不明白这个问题???




i认为本地对象存储在堆栈上(这就是为什么我没有在堆栈上创建新的
并且引用返回到

后来被覆盖的内存空间。

其他信息:
*我后来肯定需要像
res = dotproduct(Ni,nodes.column(i)); (其中Ni也是矩阵)
正常工作。(^^^^^^^^^^^^^^^临时对象)
- >操作员和方法链接。



我在这里看不到你的问题。




这有点多余我的堆栈问题。


谢谢。


-

flo


> >当你不必使用时,不要使用''new'':


cMatrix cMatrix :: row(const int& r) const
{
cMatrix tmp(1,ncols);
for(int i = 0; i< ncols; i ++)
{
tmp [i] = data [r * ncols + i];
}
返回tmp;
}

在C ++中你不必使用''new'来实现类对象。 ok。

*如何避免存储在堆栈中的对象以后被覆盖
进一步执行程序代码?



我不明白这个问题???



我以为本地对象存储在堆栈上(即



为什么我创建了不在堆栈上的新的)并且引用被返回到后来被覆盖的内存空间。




在我看来,你有一个Java思维模式。如果是这样的话,那么告诉你自己C ++不是Java,即使语法看起来很相似。

Java有引用语义,C ++有价值语义。这意味着当函数cMatrix :: row()返回tmp对象时,

将被复制

到接收返回值的对象中(你确实实现了一个副本

构造函数,是吗?)。复制tmp对象后,将销毁

。一个智能优化器可能能够优化复制,

,但这对您来说无关紧要。


如果cMatrix:您的关注是有效的: :row()将向本地对象返回引用

(cMatrix&)。你的orignal

实现cMatrix :: row()函数的另一种方法是让它返回一个

指针(cMatrix *),并将负担删除

来电者的对象。它避免了复制矩阵,但通常你想避免使用这种结构,因为这对调用者来说很不方便,而且可能导致内存泄漏。 br />

-

Peter van Merkerk

peter.van.merkerk(at)dse.nl


hello all!

i''m using gcc 3.2 on linux.
i have a (self developed) matrix class:

class cMatrix { // unneccessary info stripped
....
double *data; // matrix data is stored in a heap array

cMatrix row(const int& r) const;
// const cMatrix& row(const int& r) const; // is this better?? why?
....
const double& dotproduct(const cMatrix& m1, const cMatrix& m2) const;
....
}

cMatrix cMatrix::row(const int& r) const {
cMatrix *tmp=new cMatrix(1,ncols);
for(int i=0;i<ncols;i++) (*tmp)[i]=data[r*ncols + i];
return *tmp;
}

const double& cMatrix::dotproduct(const cMatrix& v1, const cMatrix& v2)
const {
double d=0.0;
for(int i=0;i<v1.elements();i++) d+=v1[i]*v2[i];
return d;
}
int main() {

{
cMatrix m(10,10);
cMatrix r=m.row(1);
}

return 0;
}

using valgrind i found out that the above main() leaks memory.

my questions are:
* how to alter the code of cMatrix::row to avoid memory leaks?
* how to avoid objects stored on the stack that get overriden later
when program code is further executed?
* is there a better syntax for (*tmp)[i]="some value"?

additional info:
* i later definitly need something like
res=dotproduct(Ni, nodes.column(i)); (where Ni is also a matrix)
to work correctly.(^^^^^^^^^^^^^^^ temporary object)
-> operator and method chaining.

thanks for any help or ideas!

--
flo

解决方案

"florian kno" <fl****@yahooQ.com> wrote in message
news:lV**********************@news.chello.at...

hello all!

i''m using gcc 3.2 on linux.
i have a (self developed) matrix class:

class cMatrix { // unneccessary info stripped
...
double *data; // matrix data is stored in a heap array

cMatrix row(const int& r) const;
// const cMatrix& row(const int& r) const; // is this better?? why? ...
const double& dotproduct(const cMatrix& m1, const cMatrix& m2) const; ...
}

cMatrix cMatrix::row(const int& r) const {
cMatrix *tmp=new cMatrix(1,ncols);
for(int i=0;i<ncols;i++) (*tmp)[i]=data[r*ncols + i];
return *tmp;
}

const double& cMatrix::dotproduct(const cMatrix& v1, const cMatrix& v2) const {
double d=0.0;
for(int i=0;i<v1.elements();i++) d+=v1[i]*v2[i];
return d;
}
int main() {

{
cMatrix m(10,10);
cMatrix r=m.row(1);
}

return 0;
}

using valgrind i found out that the above main() leaks memory.

my questions are:
* how to alter the code of cMatrix::row to avoid memory leaks?
Don''t use ''new'' when you don''t have to:

cMatrix cMatrix::row(const int& r) const
{
cMatrix tmp(1,ncols);
for(int i=0;i<ncols;i++)
{
tmp[i] = data[r*ncols + i];
}
return tmp;
}

In C++ you don''t have to use ''new'' to instatiate class objects.
* how to avoid objects stored on the stack that get overriden later
when program code is further executed?
I don''t understand this question???
* is there a better syntax for (*tmp)[i]="some value"?
If you don''t use pointers like in the (untested) code I showed you, you
don''t get the ugly syntax.
additional info:
* i later definitly need something like
res=dotproduct(Ni, nodes.column(i)); (where Ni is also a matrix)
to work correctly.(^^^^^^^^^^^^^^^ temporary object)
-> operator and method chaining.



I don''t see your problem here.

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl


hello!

Peter van Merkerk wrote:

"florian kno" <fl****@yahooQ.com> wrote in message
news:lV**********************@news.chello.at...

my questions are:
* how to alter the code of cMatrix::row to avoid memory leaks?



Don''t use ''new'' when you don''t have to:

cMatrix cMatrix::row(const int& r) const
{
cMatrix tmp(1,ncols);
for(int i=0;i<ncols;i++)
{
tmp[i] = data[r*ncols + i];
}
return tmp;
}

In C++ you don''t have to use ''new'' to instatiate class objects.



ok.

* how to avoid objects stored on the stack that get overriden later
when program code is further executed?



I don''t understand this question???



i was thinking that the local objects are stored on the stack (that''s why i
created new ones not on the stack) and that a reference is returned to
memory space that is later overwritten.

additional info:
* i later definitly need something like
res=dotproduct(Ni, nodes.column(i)); (where Ni is also a matrix)
to work correctly.(^^^^^^^^^^^^^^^ temporary object)
-> operator and method chaining.



I don''t see your problem here.



that''s somewhat redundant with my stack problem.

thanks.

--
flo


> > Don''t use ''new'' when you don''t have to:


cMatrix cMatrix::row(const int& r) const
{
cMatrix tmp(1,ncols);
for(int i=0;i<ncols;i++)
{
tmp[i] = data[r*ncols + i];
}
return tmp;
}

In C++ you don''t have to use ''new'' to instatiate class objects. ok.

* how to avoid objects stored on the stack that get overriden later
when program code is further executed?



I don''t understand this question???



i was thinking that the local objects are stored on the stack (that''s


why i created new ones not on the stack) and that a reference is returned to
memory space that is later overwritten.



It appears to me that you have a Java mindset. If that is the case keep
telling youself C++ is not Java, even though the syntax looks similar.
Java has reference semantics, C++ has value semantics. This means that
when the function cMatrix::row() returns the tmp object will be copied
into the object that receives the return value (you did implement a copy
constructor, did you?). After the tmp object has been copied, it will be
destroyed. A smart optimizer may be able to optimize the copying away,
but that should be of no concern to you.

Your concern would be valid if cMatrix::row() would return references
(cMatrix&) to local objects. An alternative for your orignal
implementation of the cMatrix::row() function would to let it return a
pointer (cMatrix*), and put the burden of deleting the object on the
caller. It avoids copying of the matrix but generally you want to avoid
this kind of construct, as it is inconvenient for the caller and it may
easilly lead to memory leaks.

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl


这篇关于类代码中的内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆