我正在使用cocos2d-x在C ++上开发iOS和Android游戏。我有一个实现A *寻路算法的函数。我已经在iOS上开发并测试了它,它运行完美。但是,在Android上,此功能会导致崩溃。如何在同一个设备上顺利运行相同的C ++逻辑,而不是在另一个设备上运行?
不幸的是,这个功能相当大,但无论如何我都会发布它。如果阅读时间太长,我会对一些关于可能导致一台设备设备崩溃而另一台设备设备崩溃的陷阱感到满意。这就是我认为正在发生的事情。创建一个pathStep结构(包含一些int,并且还有一个指向其初始步骤的'parent'的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 :(得分:3)
可能的原因是这一行
openList.push_back(&startStep);
很难遵循你的代码(大部分方法!)但是如果这个指针被推送到正在返回的向量,并且你取消引用这个指针,那么你有未定义的行为。您无法以任何方式返回指向本地变量的指针或引用。一旦离开范围,就定义了局部变量,该局部变量被“破坏”。
至于为什么似乎在一个平台而不是另一个平台上工作,这是因为未定义的行为是未定义的。任何事情都可能发生。
答案 1 :(得分:0)
也许是因为它达到了step index = -2125467415
的步骤索引,并且finalRoute.push_back(step);
没有得到很好的实现,因此当它转到索引为-2125467415的对象的地址时,它无法访问它并崩溃