我正在Android上开发手指绘画应用程序。我用C ++和页面卷曲一起实现了这个手指画。手指绘画效果很好,但是我想知道我的undoPen和redoPen方法中是否存在任何内存泄漏。必须使用原始指针来完成。我只添加了代码的有用部分。
vector<vector<*mPath>>MAIN(12);
vector<*mPath> undoMain(0);
int PageNo = 0;
void Pen::onFingerDown(float x1, float y1)
{
undoMain.clear();
MAIN[PageNo].push_back(move(path));
mx = x1;
my = y1;
tempPoints.x1=x1;
tempPoints.y1=y1;
tempPoints.x2=x1;
tempPoints.y2=y1;
// points.push_back(tempPoints);
path->addVert(tempPoints);
}
void Pen::onFingerMove(float x, float y)
{
tempPoints.x1=mx;
tempPoints.y1=my;
tempPoints.x2=x;
tempPoints.y2=y;
path->addVert(tempPoints);
// path->addColor(tempColors);
// points.push_back(tempPoints);
mx=x;
my=y;
//LOG_INFO("LOOOOOL");
}
void Pen::onFingerUp()
{
path = new mPath();
}
void Pen::undoPen()
{
if (MAIN[PageNo].size()>0) {
undoMain.push_back(move(*MAIN[PageNo].erase(MAIN[PageNo].end()-1)));
}
}
void Pen::redoPen()
{
if (undoMain.size()>0) {
MAIN[PageNo].push_back(move(*undoMain.erase(undoMain.end()-1)));
////
}
}
答案 0 :(得分:0)
我没有遍历您的代码,但是当您调用new而没有相应的隐式或显式删除时,您当然会发生内存泄漏,请为此使用智能指针。另外:
vector<vector<PathType>>MAIN(12); // *mPath should be a type, what is the type of mPath
vector<PathType> undoMain(0);
我会这样
vector<vector<std::unique_ptr<PathType>>>MAIN(12); //
vector<std::unique_ptr<PathType>> undoMain(0);
或者如果MAIN和undo undoMAIN都共享相同的数据
vector<vector<std::shared_ptr<PathType>>>MAIN(12); //
vector<std::shared_ptr<PathType>> undoMain(0);
实际上在示例代码中没有定义路径
编辑:
我一直在修改答案。
首先,也许您应该继续学习和深入使用C ++,而忘了托管代码,您的版本令人困惑。实际上,我们不会使用smartpointer,可以复制所有内容而没有太多副作用:
我给你改版了:
typedef vector < fingerPos > path_type; // So you low level representation of a path
// Those two must have finite limits ( no more than a given configuration dependant number )
std::deque < path_type > undo_History ( 12 ); // no need to reserve anything here ( although you can ), user input are slow.
std::deque < path_type > redo_History ( 12 )
struct Path
{
path_type mlineHolder;
Path()
{ }
void addVert ( fingerPos vert )
{
mlineHolder.push_back(vert);
}
vector < fingerPos > Path::getPath ( )
{
return ( mlineHolder );
}
~Path()
{
// no need it's automatic
// mlineHolder.clear();
// copy the current path to the Undo buffer
undo_History.push_back ( mlineHolder );
}
};
void Pen::onFingerDown(float x1, float y1)
{
// Don't undo when user begins a new drawing or you loose your buffers
// undoMain.clear ( );
// But clear the redo history since you cannot redo from something different
redo_History.clear ( );
mx = x1;
my = y1;
tempPoints.x1=x1;
tempPoints.y1=y1;
tempPoints.x2=x1;
tempPoints.y2=y1;
// points.push_back(tempPoints);
m_path->addVert ( tempPoints );
}
void Pen::onFingerMove(float x, float y)
{
tempPoints.x1=mx;
tempPoints.y1=my;
tempPoints.x2=x;
tempPoints.y2=y;
m_path->addVert(tempPoints);
// path->addColor(tempColors);
// points.push_back(tempPoints);
mx=x;
my=y;
//LOG_INFO("LOOOOOL");
}
void Pen::onFingerUp ( )
{
UndoHistory.push_front ( std::move ( m_path ) );
// Also add this path to the global structure holding every primitives on screen
}
// Undo should not be part of pen but the top level drawing manager.
void Manager::undo ( )
{
if ( UndoHistory.size ( ) ) {
redo_History. push_front ( undoMain.back ( );
}
// then redraw everything form the begining of undo history
// You must have something holding every primitives on screen that is deeper than redo history
...
}
void Pen::redoPen ( )
{
if ( redo_History .size ( ) > 0 ) {
Undo_History. push_front ( RedoMain.back ( );
// Also add this path to the global structure holding every primitives on screen
}
// then redraw everything form the begining then everything from begin to end of undo history
}
确实要将撤消历史记录添加到任何内容并不是那么容易。您必须对图形引擎有深入的了解。
希望这会有所帮助。