Сбой C ++ на Android, но не на iOS

Я разрабатываю игру на iOS и Android на C ++, используя cocos2d-x. У меня есть функция, которая реализует алгоритм поиска пути A *. Я разработал и протестировал это на iOS, и оно работает без нареканий. На Android, однако, эта функция вызывает сбой. Как это возможно, что одна и та же логика C ++ будет работать гладко на одном устройстве, но не на другом?

К сожалению, функция довольно большая, но я все равно выложу. Если это слишком долго для чтения, я буду рад некоторым общим указаниям относительно типа ловушек, которые могут вызвать сбой на одном устройстве устройства, но не на другом. Вот что я думаю, что происходит. Создается структура pathStep (которая содержит несколько целочисленных значений, а также указатель pathStep на своего «родителя» (предыдущий шаг) для начального шага. Его индекс устанавливается равным начальному индексу, а его адрес добавляется к открытый список. Однако каким-то образом, когда он извлекается из открытого списка в начале цикла, его индекс меняется с того, что было установлено на 0.

Вот функция:

std::vector<pathStep*> GameLayer::findPathBetweenPoints(int startIndex, int targetIndex){

std::list<pathStep*> openList;
std::list<pathStep*> closedList;

pathStep startStep;
startStep.index = startIndex;
startStep.fromStartDist = 0;
startStep.toEndDist = boardDistanceBetweenPoints(startIndex, targetIndex);
startStep.parent = nullptr;

openList.push_back(&startStep);

//PATH FINDING LOOP

do {

//get lowest scoring from open list

int lowestScore = 10000;
pathStep* currentStep;
int currentStepOpenListIndex;
int olIndex = 0;

for (std::list<pathStep*>::iterator i = openList.begin(); i!= openList.end(); i++) {
pathStep *step = *i;
if (step->score < lowestScore) {
currentStep = step;
lowestScore = step->score;
currentStepOpenListIndex = olIndex;
}
olIndex++;
}
Hexagon *currentHexagon = _hexagons.at(currentStep->index);

//check if it is the target
if (currentStep->index == targetIndex) {
cocos2d::log("target found!!!!!");
//return route between points
std::vector<pathStep*> finalRoute;
pathStep *step = currentStep;
for (; ; ) {
cocos2d::log("step index = %d", step->index);

finalRoute.push_back(step);
if (step->index == startIndex) {
return finalRoute;
}
step = step->parent;
}
}

//remove the current step from the open list and add it to the closed list
std::list<pathStep*>::iterator iterator = openList.begin();
std::advance(iterator, currentStepOpenListIndex);
openList.erase(iterator);

closedList.push_back(currentStep);

//get the adjacent nodes
std::vector<pathStep*> walkableSteps = currentHexagon->getWalkableSteps();
cocos2d::log("num walkable steps returned by hexagon at index %d is %lu", currentHexagon->getIndex(), walkableSteps.size());

//set the parent to the current node
for (int i = 0; i < walkableSteps.size(); i++) {
pathStep *step = walkableSteps.at(i);
step->parent = currentStep;

}

//score the walkable steps and add to open list if not already in either list
for (int i = 0; i < walkableSteps.size(); i++) {

pathStep *step = walkableSteps.at(i);
step->fromStartDist = currentStep->fromStartDist +1;
step->toEndDist = boardDistanceBetweenPoints(step->index, targetIndex);
step->score = step->fromStartDist + step->toEndDist;

bool isInOpenList = false;
bool isInClosedList = false;

//check if is in open list
for (std::list<pathStep*>::iterator i = openList.begin(); i!= openList.end(); i++) {
pathStep *olStep = *i;
if (olStep->index == step->index) {
isInOpenList = true;
}
}
//check if is closed list
for (std::list<pathStep*>::iterator i = closedList.begin(); i!= closedList.end(); i++) {
pathStep *clStep = *i;
if (clStep->index == step->index) {
isInClosedList = true;
}
}

//if is not in either list, add to the open list
if (isInClosedList == false && isInOpenList == false) {
openList.push_back(step);
}

}

} while (openList.size() != 0);

cocos2d::log("couldn't find valid path");
std::vector<pathStep*> path;
return path;
}

Вот журналы консоли от успешного запуска на iOS:

hexagon index 12 //this is the start position
hexagon index 36 //this is the end position
num walkable steps returned by hexagon at index 12 is 4 //from the start position, finds the shortest route to the end position
num walkable steps returned by hexagon at index 21 is 5
num walkable steps returned by hexagon at index 11 is 4
num walkable steps returned by hexagon at index 29 is 6
num walkable steps returned by hexagon at index 20 is 5
num walkable steps returned by hexagon at index 10 is 5
num walkable steps returned by hexagon at index 38 is 6
num walkable steps returned by hexagon at index 28 is 5
num walkable steps returned by hexagon at index 37 is 5
num walkable steps returned by hexagon at index 27 is 4
target found!!!!!
step index = 36 //printing the route back to the start position
step index = 37
step index = 38
step index = 29
step index = 21
step index = 12
go taken //success!

Вот журналы консоли от неудачного запуска на Android:

hexagon index 25 //this is the start position
hexagon index 38 //this is the end position
num walkable steps returned by hexagon at index 0 is 1 //Android always starts at index 0, this looks like it is where the problem arises
num walkable steps returned by hexagon at index 9 is 4
num walkable steps returned by hexagon at index 19 is 6
num walkable steps returned by hexagon at index 18 is 3
num walkable steps returned by hexagon at index 10 is 5
num walkable steps returned by hexagon at index 28 is 5
target found!!!!!
step index = 38
step index = 28
step index = 19
step index = 9
step index = 0
step index = -2125467415 //follows the pointers back until it finds start index, as the initial index was incorrect, keeps going until it ends up in undefined memory
Fatal signal 11 (SIGSEGV) at 0x0a58e044 (code=1), thread 862 (ren.numberboard)

Наконец, вот журнал сбоев от Android (который, кажется, не говорит мне много):

********** Crash dump: **********
Build fingerprint: 'generic/sdk/generic:4.3/JWR66V/737497:eng/test-keys'
pid: 778, tid: 793, name: UNKNOWN  >>> com.stevebarnegren.numberboard <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0a58e044
Assertion failed: (debug_str_.is_mapped() && index < debug_str_.size()), function get_debug_str, file elff/elf_file.h, line 300.
Stack frame #00  pc 001633d4  /data/app-lib/com.stevebarnegren.numberboard-1/libcocos2dcpp.so (GameLayer::findPathBetweenPoints(int, int)+147)Abort trap: 6

Спасибо за любую помощь!

0

Решение

Вероятной причиной является эта линия

openList.push_back(&startStep);

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

Что касается того, почему работает на одной платформе, а не на другой, это потому, что неопределенное поведение, ну, в общем, неопределенное. Может произойти все, что угодно.

3

Другие решения

Может быть, потому что он достиг шага индекса step index = -2125467415, а также finalRoute.push_back(step); не очень хорошо реализован, поэтому, когда он идет по адресу объекта с индексом -2125467415, он не может получить к нему доступ и вылетает

0