帮我看看我这个寻路程序的问题
报错
return value 3221225477
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STARTNODE 2
#define ENDNODE 3
#define BARRIER 1
typedef struct AStarNode
{
int s_x; // 坐标(最终输出路径需要)
int s_y; // 坐标(最终输出路径需要)
int s_g; // 起点到此点的距离( 由g和h可以得到f,此处f省略,f=g+h )
int s_h; // 启发函数预测的此点到终点的距离
int s_style; // 结点类型:起始点,终点,障碍物
struct AStarNode * s_parent; // 父节点
int s_is_in_closetable; // 是否在close表中
int s_is_in_opentable; // 是否在open表中
}AStarNode, *pAStarNode;
AStarNode map_maze[21][21]; // 结点数组
pAStarNode open_table[500000]; // open表
pAStarNode close_table[500000]; // close表
int open_node_count; // open表中节点数量
int close_node_count; // close表中结点数量
pAStarNode path_stack[500000]; // 保存路径的栈
int top = -1; // 栈顶
// 交换两个元素
void swap( int idx1, int idx2 )
{
pAStarNode tmp = open_table[idx1];
open_table[idx1] = open_table[idx2];
open_table[idx2] = tmp;
}
void clear() //清空数组
{
memset(path_stack, 0, sizeof path_stack);
memset(close_table, 0, sizeof close_table);
memset(open_table, 0, sizeof open_table);
}
// 堆调整
void adjust_heap( int nIndex )
{
int curr = nIndex;
int child = curr * 2 + 1; // 得到左孩子idx( 下标从0开始,所有做孩子是curr*2+1 )
int parent = ( curr - 1 ) / 2; // 得到双亲idx
if (nIndex < 0 || nIndex >= open_node_count)
{
return;
}
// 往下调整( 要比较左右孩子和cuur parent )
while ( child < open_node_count )
{
// 小根堆是双亲值小于孩子值
if ( child + 1 < open_node_count && open_table[child]->s_g + open_table[child]->s_h > open_table[child+1]->s_g + open_table[child+1]->s_h )
{
++child;// 判断左右孩子大小
}
if (open_table[curr]->s_g + open_table[curr]->s_h <= open_table[child]->s_g + open_table[child]->s_h)
{
break;
}
else
{
swap( child, curr ); // 交换节点
curr = child; // 再判断当前孩子节点
child = curr * 2 + 1; // 再判断左孩子
}
}
if (curr != nIndex)
{
return;
}
// 往上调整( 只需要比较curr child和parent )
while (curr != 0)
{
if (open_table[curr]->s_g + open_table[curr]->s_h >= open_table[parent]->s_g + open_table[parent]->s_h)
{
break;
}
else
{
swap( curr, parent );
curr = parent;
parent = (curr-1)/2;
}
}
}
// 判断邻居点是否可以进入open表
void insert_to_opentable( int x, int y, pAStarNode curr_node, pAStarNode end_node, int w )
{
int i;
if ( map_maze[x][y].s_style != BARRIER ) // 不是障碍物
{
if ( !map_maze[x][y].s_is_in_closetable ) // 不在闭表中
{
if ( map_maze[x][y].s_is_in_opentable ) // 在open表中
{
// 需要判断是否是一条更优化的路径
if ( map_maze[x][y].s_g > curr_node->s_g + w ) // 如果更优化
{
map_maze[x][y].s_g = curr_node->s_g + w;
map_maze[x][y].s_parent = curr_node;
for ( i = 0; i < open_node_count; ++i )
{
if ( open_table[i]->s_x == map_maze[x][y].s_x && open_table[i]->s_y == map_maze[x][y].s_y )
{
break;
}
}
adjust_heap( i ); // 下面调整点
}
}
else // 不在open中
{
map_maze[x][y].s_g = curr_node->s_g + w;
map_maze[x][y].s_h = abs(end_node->s_x - x ) + abs(end_node->s_y - y);
map_maze[x][y].s_parent = curr_node;
map_maze[x][y].s_is_in_opentable = 1;
open_table[open_node_count++] = &(map_maze[x][y]);
}
}
}
}
// 查找邻居
// 对上下左右8个邻居进行查找
void get_neighbors( pAStarNode curr_node, pAStarNode end_node )
{
int x = curr_node->s_x;
int y = curr_node->s_y;
// 下面对于4个邻居进行处理
if ( ( x + 1 ) >= 0 && ( x + 1 ) < 21 && y >= 0 && y < 21 )
{
insert_to_opentable( x+1, y, curr_node, end_node, 10 );
}
if ( ( x - 1 ) >= 0 && ( x - 1 ) < 21 && y >= 0 && y < 21 )
{
insert_to_opentable( x-1, y, curr_node, end_node, 10 );
}
if ( x >= 0 && x < 21 && ( y + 1 ) >= 0 && ( y + 1 ) < 21 )
{
insert_to_opentable( x, y+1, curr_node, end_node, 10 );
}
if ( x >= 0 && x < 21 && ( y - 1 ) >= 0 && ( y - 1 ) < 21 )
{
insert_to_opentable( x, y-1, curr_node, end_node, 10 );
}
}
int main()
{
AStarNode *start_node; // 起始点
AStarNode *end_node; // 结束点
AStarNode *curr_node; // 当前点
int is_found; // 是否找到路径
int tarn[20]={19,0,19,3,9,9,19,0,1,20}; //目标点集
int x1,y1,x2,y2; //目标点坐标
int t;
for(t=0;t<7;t=t+2)
{
int maze[21][21] ={ // 导入地图
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0},
{1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,1,1},
{1,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,1},
{1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,1,1,0,1},
{1,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,1},
{1,1,1,0,1,0,1,0,1,1,1,1,1,0,1,1,1,0,1,1,1},
{1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,1},
{1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1},
{1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1},
{1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,0,1,1,1,0,1},
{1,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,1},
{1,1,1,0,1,1,1,0,1,1,1,1,1,0,1,0,1,0,1,1,1},
{1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,1},
{1,0,1,1,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1},
{1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,1},
{1,1,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1},
{0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};
x1=tarn[t];
y1=tarn[t+1];
x2=tarn[t+2];
y2=tarn[t+3];
maze[x1][y1]=2;
maze[x2][y2]=3; //定义起点和终点
int i,j;
// 下面准备点
for( i = 0; i < 21; ++i )
{
for ( j = 0; j < 21; ++j )
{
map_maze[i][j].s_g = 0;
map_maze[i][j].s_h = 0;
map_maze[i][j].s_is_in_closetable = 0;
map_maze[i][j].s_is_in_opentable = 0;
map_maze[i][j].s_style = maze[i][j];
map_maze[i][j].s_x = i;
map_maze[i][j].s_y = j;
map_maze[i][j].s_parent = NULL;
if ( map_maze[i][j].s_style == STARTNODE ) // 起点
{
start_node = &(map_maze[i][j]);
}
else if( map_maze[i][j].s_style == ENDNODE ) // 终点
{
end_node = &(map_maze[i][j]);
}
//printf("%d ", maze[i][j]); //输出地图
}
//printf("\n");
}
// 使用A*算法得到路径
open_table[open_node_count++] = start_node; // 起始点加入open表
start_node->s_is_in_opentable = 1; // 加入open表
start_node->s_g = 0;
start_node->s_h = abs(end_node->s_x - start_node->s_x) + abs(end_node->s_y - start_node->s_y);
start_node->s_parent = NULL;
is_found = 0;
while( 1 )
{
curr_node = open_table[0]; // open表的第一个点一定是f值最小的点(通过堆排序得到的)
open_table[0] = open_table[--open_node_count]; // 最后一个点放到第一个点,然后进行堆调整
adjust_heap( 5 ); // 调整堆
close_table[close_node_count++] = curr_node; // 当前点加入close表
curr_node->s_is_in_closetable = 1; // 已经在close表中了
if ( curr_node->s_x == end_node->s_x && curr_node->s_y == end_node->s_y )// 终点在close中,结束
{
is_found = 1;
break;
}
get_neighbors( curr_node, end_node ); // 对邻居的处理
if ( open_node_count == 0 ) // 没有路径到达
{
is_found = 0;
break;
}
}
if ( is_found )
{
curr_node = end_node;
while( curr_node )
{
path_stack[++top] = curr_node;
curr_node = curr_node->s_parent;
}
while(top<=7 && top >= 0 ) // 输出路径
{
printf("(%d,%d)-->", path_stack[top]->s_x, path_stack[top]->s_y);
top--;
}
while(top>=8)
{
for( int p = 0; p <8 ;p++ )
{
printf("(%d,%d)-->", path_stack[top]->s_x, path_stack[top]->s_y);
top--;
}
top++;
tarn[t]=path_stack[top]->s_x ;
tarn[t+1]=path_stack[top]->s_y ;
t=t-2;
printf("\n");
memset( path_stack, 0x00, sizeof(*path_stack) );
is_found = 0;
}
printf("\n");
}
//clear();
}
}
这个问题的错误代码3221225477在Windows中通常表示程序崩溃,可能是由于访问了无效的内存地址或者出现了堆栈溢出等问题。
检查你的代码,我注意到你定义了一些非常大的数组,例如:
pAStarNode open_table[500000]; // open表
pAStarNode close_table[500000]; // close表
pAStarNode path_stack[500000]; // 保存路径的栈
这些数组都是静态分配的,它们会占用大量的栈空间。如果你在一个有限制的环境下(如默认设置下的Visual Studio),可能会因为超出最大栈大小而导致程序崩溃。
解决此问题可以有两种方式:
减小数组大小:如果你确信实际使用时这些数组不会被全部填满,那么可以尝试减小它们的大小。
动态分配内存:使用动态内存分配函数如malloc(对于C)或new(对于C++)来分配这些大型数组。动态分配内存不会占用栈空间,因此不会导致堆栈溢出。但请注意,动态分配内存需要手动释放,否则可能导致内存泄漏。
例如,将上述代码修改为:
pAStarNode* open_table = (pAStarNode*)malloc(500000 * sizeof(pAStarNode));
// ... 使用open_table ...
free(open_table); // 当open_table不再需要时释放其占用的内存
此外,请确保所有对这些大型数组的访问都在有效范围内,并且没有其他可能导致无效内存访问或其他形式崩溃的行为。