0 c++ memory optimization memory-management
我现在正在编写用于图像处理的小应用程序.但是我的程序内存使用存在很大问题.我是c ++的新手,以前我主要用c#编程.
几乎所有工作的功能都是这样的
while(!prototypeVector[i]->GetIsConvergaed())
{
if(previousPrototype!=NULL) delete previousPrototype;
previousPrototype = prototypeVector[i]->CopyPrototype();
if(&matchingPointVector!=NULL) matchingPointVector.clear();
matchingPointVector = prototypeVector[i]->CalculateMatchingPointsAll(imageDataVector);
distanseMatrix = CalculateDistanceAll(i);
membershipMatrix = UpdateMembershipAll(i);
if(translation)
{
tmatrix = UpdateTranslationMatrix(i);
if(directUpdate) prototypeVector[i]->SetTranslationMatrix( tmatrix);
//prototypeVector[i]->GetTranslationMatrix().DisplayMatrix();
tmatrix.DisplayMatrix();
}
if(scaling)
{
smatrix = UpdateScalingMatrix(i);
if(directUpdate) prototypeVector[i]->SetScalingMatrix(smatrix);
smatrix.DisplayMatrix();
}
if(rotation)
{
angle = UpdateAngleCoefficient(i);
cout<<endl;
Convert::RadiansToDegrees(angle)<<endl;
if(directUpdate)prototypeVector[i]->UpdateRotationMatrix(angle);
}
prototypeVector[i]->TransformTemplateOne(prototypeVector[i]->GetRotationMatrix(), prototypeVector[i]->GetScalingMatrix() , prototypeVector[i]->GetTranslationMatrix());
}
Run Code Online (Sandbox Code Playgroud)
我注意到如果在上面写的函数被称为另一个函数
CalculateMatchingPointsAll或CalculateDistanceAll或UpdateScalingMatrix内存使用率大幅上升(执行上述每个函数后300kB).所以我认为问题出在这些功能上.他们看起来像那样
vector<Point*> TemplateClusterPoint::CalculateMatchingPointsAll( vector<Point*> imageDataVector)
{
vector<Point*> matchinPointVector = vector<Point*>(imageDataVector.size(),new Point(0,0));
double minValue = DOUBLE_MAX_VALUE;
double currentDistance = 0;
for (int i=0;i<imageDataVector.size();i++ )
{
//matchinPointVector[i] = this->CalculateMatchingPoint(/*prototypePointVector,*/imageDataVector[i]);
for (int j=0;j<prototypePointVector.size();j++)
{
if( (currentDistance = CalculateDistance(imageDataVector[i],prototypePointVector[j]) ) <= minValue )
{
minValue = currentDistance;
matchinPointVector[i] = prototypePointVector[j];
}
}
minValue = currentDistance = DOUBLE_MAX_VALUE;
}
return matchinPointVector;
}
vector<vector<double>> AlgorithmPointBased::CalculateDistanceAll( int clusterIndex)
{
//vector<Point*> pointVector = prototypeVector[clusterIndex]->GetPrototypePointVector();
Point* firstPoint = NULL;
Point* secondPoint = NULL;
for(int i=0;i<imageDataVector.size();i++ )
{
firstPoint = imageDataVector[i];
secondPoint = matchingPointVector[i];
distanseMatrix[clusterIndex][i] = pow( (firstPoint->GetX() - secondPoint->GetX() ), 2 ) + pow( (firstPoint->GetY() - secondPoint->GetY() ), 2); //(difference*difference)[0][0]; //funkcja dystansu = d^2 = (Xi - Pji)^2
// gdzie Xi punkt z obrazu, Pij matching point w danym klastrze
}
return distanseMatrix;
}
Matrix<double> AlgorithmPointBased::UpdateScalingMatrix( int clusterIndex )
{
double currentPower = 0;
vector<Point*> prototypePointVecotr = prototypeVector[clusterIndex]->GetPrototypePointVector();
vector<Point*> templatePointVector = templateCluster->GetTemplatePointVector();
Point outcomePoint;
Matrix<double> numerator = Matrix<double>(1,1,0);
double denominator=0;
for (int i=0;i< imageDataVector.size();i++)
{
Point templatePoint = *matchingPointVector[i];
currentPower = pow(membershipMatrix[clusterIndex][i],m);
numerator += / ((*imageDataVector[i] - prototypeVector[clusterIndex]->GetTranslationMatrix()).Transpose()* (prototypeVector[clusterIndex]->GetRotationMatrix() * templatePoint )* currentPower);
denominator += (currentPower* (pow(templatePoint.GetX(),2) + pow(templatePoint.GetY(),2)));
}
numerator /= denominator;
return numerator;
}
Run Code Online (Sandbox Code Playgroud)
正如您可以看到,这些功能所做的几乎所有工作都是计算新点或最近点或对图像进行转换.有没有办法在执行这些函数后以某种方式释放至少一些内存.我认为占用大多数内存的操作是矩阵的乘法或点上的操作.我重载了operator +*和/当然返回了新对象.
EDITED重载运算符看起来像那样
Point Point::operator*( double varValue )
{
return *(new Point(this->x * varValue,this->y * varValue));
}
Point Point::operator-( Point& secondPoint )
{
return *(new Point(this->x - secondPoint.GetX(),this->y - secondPoint.GetY()));
}
Point Point::operator*( double varValue )
{
return *(new Point(this->x * varValue,this->y * varValue));
}
template<typename T>
Matrix<T> Matrix<T>::operator + (double value)
{
Matrix<T>* addedMatrix = new Matrix<T>(this->rows,this->columns);
for (int i=0;i<this->rows;i++)
{
for (int j=0;j<this->columns;j++)
{
(*addedMatrix)[i][j] = (*this)[i][j]+ value;
}
}
return *addedMatrix;
}
Point Point::operator/( double varValue )
{
return *(new Point(this->x / varValue,this->y / varValue));
}
Run Code Online (Sandbox Code Playgroud)
Jam*_*lis 10
我是C++中的新手,以前我主要用C#编程.
与C#不同,C++没有垃圾收集.无论何时使用new(例如new Point(0,0)),您都有责任使用它delete来销毁该对象.
理想情况下,您应该避免显式地动态分配对象,并避免new和delete完全避开.您应该更喜欢创建具有自动存储持续时间的对象(在堆栈上)并使用它们的副本(通过按值或引用传递它们,按值返回它们,并将它们的副本存储在容器中).
除此之外,你几乎肯定会使用a std::vector<Point>而不是a std::vector<Point*>.
Run Code Online (Sandbox Code Playgroud)return *(new Point(this->x * varValue,this->y * varValue));
所有具有此类代码的函数都是错误的:您动态分配对象,返回该对象的副本,并丢失对原始对象的所有引用.你没有办法破坏动态分配的对象.您不需要在此处动态分配任何内容.以下就足够了:
return Point(x * varValue, y * varValue);
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)if(&matchingPointVector!=NULL)
在正确的程序中,这永远不会是错误的: &获取对象的地址,没有对象可以拥有该地址NULL.唯一可能发生这种情况的方法是,如果你已经在程序的某个地方取消引用了一个空指针,那么你就已经遇到了麻烦.
确保你有一本很好的入门C++书.C++和C#是非常不同的编程语言.