Отменить / повторить в C ++ Android утечка памяти - PullRequest
0 голосов
/ 27 августа 2018

Я разрабатываю приложение для рисования пальцем на 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)));

        ////
    }
}

1 Ответ

0 голосов
/ 27 августа 2018

Я не просматривал ваш код, но, конечно, у вас возникают утечки памяти, когда вы вызываете 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, и undoMAIN отменены, и те же данные имеют

vector<vector<std::shared_ptr<PathType>>>MAIN(12); // 
vector<std::shared_ptr<PathType>> undoMain(0);

На самом деле путь не указан в вашем примере кода

EDIT:

Я переделываю свой ответ.

Во-первых, может быть, вам следует продолжить изучение и углубиться в C ++ и забыть об управляемом коде, ваша версия сбивает с толку. На самом деле мы не будем использовать smartpointers, все можно скопировать без особых побочных эффектов:

Я даю вам переработанную версию:

    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
}

Действительно, добавить историю отмены во что-то не так просто. Вы должны глубоко понять свой графический движок.

Надеюсь, это поможет.

...