android - C++ Android内存泄漏中的撤消/重做
问题描述
我正在 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)));
////
}
}
解决方案
我没有仔细阅读您的代码,但是当然,每当您在没有相应的隐式或显式删除的情况下调用 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++,忘记托管代码,您的版本令人困惑。事实上我们不会使用智能指针,一切都可以复制而没有太多副作用:
我给你一个修改后的版本:
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
}
确实,向任何事物添加撤消历史记录并不是那么容易。您必须深入了解您的图形引擎。
希望这能有所帮助。
推荐阅读
- javascript - how to call a service using ajax javascript?
- visual-studio - Visual Studio 2019 尝试加载文件夹时出错
- javascript - 使用多维数组创建动态表并将数据存储在状态中
- apache-spark-sql - Spark SQL vs Hive vs Presto SQL 在 Parquet 文件上进行分析
- javascript - Javascript - 如何知道 devtools 中 Js 路径的确切长度
- javascript - 阻止 div 在桌子上重叠
- oracle-apex - 如何从 Oracle APEX 页面调用 Jira Rest API
- mysql - Mysql 从表中选择顶部项目然后删除并打印
- web - urllib.request 模块发出的请求和浏览器发出的请求一样吗?
- python - Python蜘蛛在文件上写空行时显示数据框的行元素