【问题标题】:C++ crash on Android but not on iOSC++ 在 Android 上崩溃,但在 iOS 上没有
【发布时间】:2013-10-29 11:24:07
【问题描述】:

我正在使用 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

感谢您的帮助!

【问题讨论】:

    标签: android c++ crash cocos2d-x a-star


    【解决方案1】:

    可能的原因是这条线

    openList.push_back(&startStep);
    

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

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

    【讨论】:

    • 原来我没有初始化 startStep 结构的一个元素(一个 int),这导致了问题。因此,行为上的差异似乎在于,在 iOS 上,结构的成员将被初始化为 0,但在 Android 上,它们未初始化。感谢您指出我不应该返回局部变量的指针,我已经更改了代码以使用“new”来分配内存。 (有趣的是,如果在 iOS 上使用“new”创建结构,则不会为您初始化成员)。感谢您的帮助,直到上周我才使用 Objective-C,所以这是我第一次涉足 C++
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-19
      相关资源
      最近更新 更多