gpt4 book ai didi

C:段错误:GDB:<错误读取变量>

转载 作者:行者123 更新时间:2023-12-04 09:32:31 25 4
gpt4 key购买 nike

我有一个函数 shortestPath(),它是 Dijkstra 算法的修改实现,用于我正在为我的 comp2 类工作的棋盘游戏 AI。我浏览了网站并使用 gdb 和 valgrind 我确切地知道段错误发生的位置(实际上几个小时前就知道了),但无法弄清楚是什么未定义的行为或逻辑错误导致了问题。

出现问题的函数被调用大约 10 倍并按预期工作,直到它与 GDB 发生段错误:
“错误读取变量:无法访问内存”
和瓦尔格林:
“大小 8 的无效读取”

通常这已经足够了,但我无法解决这个问题。也感谢任何一般性建议和提示......谢谢!

GDB:https://gist.github.com/mckayryan/b8d1e9cdcc58dd1627ea
Valgrind:https://gist.github.com/mckayryan/8495963f6e62a51a734f

这是发生段错误的函数:

static void processBuffer (GameView currentView, Link pQ, int *pQLen, 
LocationID *buffer, int bufferLen, Link prev,
LocationID cur)
{
//printLinkIndex("prev", prev, NUM_MAP_LOCATIONS);
// adds newly retrieved buffer Locations to queue adding link types
appendLocationsToQueue(currentView, pQ, pQLen, buffer, bufferLen, cur);
// calculates distance of new locations and updates prev when needed
updatePrev(currentView, pQ, pQLen, prev, cur); <--- this line here

qsort((void *) pQ, *pQLen, sizeof(link), (compfn)cmpDist);
// qsort sanity check
int i, qsortErr = 0;
for (i = 0; i < *pQLen-1; i++)
if (pQ[i].dist > pQ[i+1].dist) qsortErr = 1;
if (qsortErr) {
fprintf(stderr, "loadToPQ: qsort did not sort succesfully");
abort();
}
}

以及在它被调用后一切都崩溃的函数:
static void appendLocationsToQueue (GameView currentView, Link pQ, 
int *pQLen, LocationID *buffer,
int bufferLen, LocationID cur)
{
int i, c, conns;
TransportID type[MAX_TRANSPORT] = { NONE };

for (i = 0; i < bufferLen; i++) {
// get connection information (up to 3 possible)
conns = connections(currentView->gameMap, cur, buffer[i], type);
for (c = 0; c < conns; c++) {
pQ[*pQLen].loc = buffer[i];
pQ[(*pQLen)++].type = type[c];
}
}
}

所以我认为一个指针已被覆盖到错误的地址,但在 GDB 中进行了大量打印后,情况似乎并非如此。我还轮流读取/写入相关变量以查看哪个触发了错误,它们都在 appendLocationsToQueue() 之后执行,但不是之前(或在该函数的末尾)。

以下是相关代码的其余部分:
最短路径():
Link shortestPath (GameView currentView, LocationID from, LocationID to, PlayerID player, int road, int rail, int boat)
{
if (!RAIL_MOVE) rail = 0;

// index of locations that have been visited
int visited[NUM_MAP_LOCATIONS] = { 0 };

// current shortest distance from the source
// the previous node for current known shortest path
Link prev;
if(!(prev = malloc(NUM_MAP_LOCATIONS*sizeof(link))))
fprintf(stderr, "GameView.c: shortestPath: malloc failure (prev)");

int i;
// intialise link data structure
for (i = 0; i < NUM_MAP_LOCATIONS; i++) {
prev[i].loc = NOWHERE;
prev[i].type = NONE;
if (i != from) prev[i].dist = INF;
else prev[i].dist = LAST;
}
LocationID *buffer, cur;
// a priority queue that dictates the order LocationID's are checked
Link pQ;
int bufferLen, pQLen = 0;
if (!(pQ = malloc(MAX_QUEUE*sizeof(link))))
fprintf(stderr, "GameView.c: shortestPath: malloc failure (pQ)");
// load initial location into queue
pQ[pQLen++].loc = from;

while (!visited[to]) {
// remove first item from queue into cur
shift(pQ, &pQLen, &cur);
if (visited[cur]) continue;
// freeing malloc from connectedLocations()
if (cur != from) free(buffer);
// find all locations connected to
buffer = connectedLocations(currentView, &bufferLen, cur,
player, currentView->roundNum, road,
rail, boat);
// mark current node as visited
visited[cur] = VISITED;
// locations from buffer are used to update priority queue (pQ)
// and distance information in prev
processBuffer(currentView, pQ, &pQLen, buffer, bufferLen, prev,
cur);
}
free(buffer);
free(pQ);
return prev;
}

最佳答案

在此行之前您的所有参数看起来都不错的事实:

appendLocationsToQueue(currentView, pQ, pQLen, buffer, bufferLen, cur);

并且在它告诉我你踩到(写 0x7fff00000000 到) $rbp 后变得不可用注册(所有局部变量和参数都是相对于 $rbp 在没有优化的情况下构建的)。

您可以在 GDB 中使用 print $rbp 确认这一点。前后调用 appendLocationsToQueue ( $rbp 应该在给定函数内始终具有相同的值,但会发生变化)。

假设这是真的,发生这种情况的方式只有几种,最可能的方式是 appendLocationsToQueue 中的堆栈缓冲区溢出。 (或它调用的东西)。

您应该能够使用 Address Sanitizer ( g++ -fsanitize=address ... ) 轻松找到此错误。

在 GDB 中找到溢出也相当容易:进入 appendLocationsToQueue ,然后做 watch -l *(char**)$rbp , continue .当您的代码覆盖 $rbp 时,应该触发观察点保存位置。

关于C:段错误:GDB:<错误读取变量>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33124848/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com