0

我正在使用 cocos2d-x 在 C++ 中开发 iOS 和 Android 上的游戏。我有一个实现 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

谢谢你的帮助!

4

2 回答 2

3

可能的原因是这条线

openList.push_back(&startStep);

很难遵循您的代码(很多方法!)但是如果这个指针曾经被推送到要返回的向量,并且您取消引用这个指针,那么您就有未定义的行为。您不能以任何方式返回对局部变量的指针或引用。一旦离开范围,定义了一个局部变量,该局部变量就被“破坏”了。

至于为什么似乎在一个平台上而不是在另一个平台上工作,这是因为未定义的行为是未定义的。什么事情都可能发生。

于 2013-10-29T11:29:36.020 回答
0

可能是因为它达到了 step 索引step index = -2125467415,并且finalRoute.push_back(step);没有很好地实现,所以当它到达索引为 -2125467415 的对象的地址时,它无法访问它并崩溃

于 2013-10-29T11:35:29.827 回答