Использование push_back () для списка STL в C ++ вызывает нарушение прав доступа, сбой - PullRequest
1 голос
/ 08 октября 2011

Я создаю игру, используя свой собственный самодельный игровой движок, но у меня возникают проблемы с использованием списков.

В моей программе есть структура BoardState. Каждая из этих структур имеет список указателей BoardState, называемых дочерними. Это потому, что я создаю дерево BoardStates для AI моей игры.

Чтобы помочь в создании моего дерева, у меня есть функция под названием MakeBoard. Эта функция передает всю информацию, необходимую для создания новой доски, и затем она должна добавить указатель на эту новую доску в конец списка дочерних элементов родительской платы. Вот соответствующая функция, MakeBoard:

void MakeBoard(BoardState* pStartBoard, int iPiece, int iPosStart, int iPosFinish, int* pJumpArray)

{

//BoardState* pNewBoard = &NewBoard;
//pNewBoard->bPlayerTurn = !(pStartBoard->bPlayerTurn);
//NewBoard.bPlayerTurn = !(pStartBoard->bPlayerTurn);
BoardState* pNewBoard = (BoardState*)malloc(sizeof(BoardState));

pNewBoard->bPlayerTurn = !(pStartBoard->bPlayerTurn);

// Copy the BoardPositions of the starting board into the new Board.
for(int i = 0; i < 37; i++)
{
    pNewBoard->posArray[i] = pStartBoard->posArray[i];
    //NewBoard.posArray[i] = pStartBoard->posArray[i];
}

// Make the BoardPosition change necessary to reflect the move.
pNewBoard->posArray[iPosStart] = -1;
pNewBoard->posArray[iPosFinish] = iPiece;

//NewBoard.posArray[iPosStart] = -1;
//NewBoard.posArray[iPosFinish] = iPiece;

// Now account for any pieces that were jumped, if applicable.
if(pJumpArray != NULL)
{
    for(int i = 0; i < 16; i++)
    {
        if(pJumpArray[i] != -1)
        {
            pNewBoard->posArray[pJumpArray[i]] = -1;
            //NewBoard.posArray[pJumpArray[i]] = -1;
        }
    }
}

// Connect the parent board to this child board.
pNewBoard->parent = pStartBoard;
//NewBoard.parent = pStartBoard;

//pStartBoard->children.push_back(_pTestState);

pStartBoard->children.push_back(pNewBoard); // <- The problem

//pStartBoard->children.push_back(&NewBoard);

}

В дополнительных комментариях я попробовал другие идеи, чтобы проверить, сработали ли они.

К сожалению, это приводит к тому, что программа выдает следующую ошибку:

Место чтения нарушения доступа 0xcdcdcdd1.

Если я копаюсь в отладчике, я обнаруживаю, что проблема возникает в файле списка STL. Это три верхних вызова в стеке вызовов:

OpenGL_Engine_Test1.exe! Std :: list> :: _ Вставить (std :: list> :: _ Const_iterator <1> _Where = ..., tagBoardState * const & _Val = 0x049a1a80) Строка 718 + 0x10 байт C ++

OpenGL_Engine_Test1.exe!std::list<tagBoardState *,std::allocator<tagBoardState *> >::push_back(tagBoardState * const & _Val=0x049a1a80)  Line 670 + 0x51 bytes  C++

OpenGL_Engine_Test1.exe!MakeBoard(tagBoardState * pStartBoard=0x049a0580, int iPiece=16, int iPosStart=21, int iPosFinish=16, int * pJumpArray=0x00000000)  Line 352    C++

Затем он открывает файл, в котором определен список, и указывает на проблемную строку внутри функции _insert:

void _Insert (const_iterator _Where, const _Ty & _Val) {// вставить _Val в _Where

# if _HAS_ITERATOR_DEBUGGING если (_Where._Mycont! = это) _DEBUG_ERROR («Итератор вставки списка вне диапазона»); #endif / * _HAS_ITERATOR_DEBUGGING * /

    _Nodeptr _Pnode = _Where._Mynode();
    _Nodeptr _Newnode = _Buynode(_Pnode, _Prevnode(_Pnode), _Val); // PROBLEM
    _Incsize(1);
    _Prevnode(_Pnode) = _Newnode;
    _Nextnode(_Prevnode(_Newnode)) = _Newnode;
    }

Помимо этого, я не знаю больше. Я понятия не имею, почему эта проблема возникает. Я знаю, что «Нарушение прав доступа» в основном означает, что я либо пытаюсь получить доступ к чему-то, что не существует, у меня нет доступа, или есть какая-то проблема с областью видимости, но я не вижу, как из них применимы.

Если кто-нибудь может указать мне правильное направление, я был бы очень признателен. Я много занимался поиском, но почти все, что я нашел, касалось Векторов и, похоже, не являлось моей проблемой.

Ответы [ 2 ]

6 голосов
/ 08 октября 2011

Если вы используете malloc () для класса C ++, никакие конструкторы не будут вызываться ни для одного из полей этого класса, включая ваш проблемный вектор. Вам нужно использовать новый.

Я сделал предположение, что pStartBoard был выделен так же, как pNewBoard, но у вас будет такая же проблема в pNewBoard, даже если это не так.

0 голосов
/ 08 октября 2011

Место чтения нарушения доступа 0xcdcdcdd1. Указывает на унифицированную переменную. Отладчик помещает такие значения в качестве маркеров. К сожалению, я не могу определить, где вы видите ошибку, ни какие-либо контейнеры STL в вашем примере кода. Но 'pNewBoard-> posArray' будет первым местом, куда я посмотрю. Устанавливает ли конструктор этого класса что-либо в этот элемент?

...