【发布时间】:2020-11-28 13:00:55
【问题描述】:
我正在编写一个程序,它使用以下结构来存储信息:
/* Structure used to hold a graph vertex information. */
typedef struct graph_vertex
{
int identifier;
struct graph_vertex *next_vertex_p;
struct graph_edge *edge_list_p;
boolean_t visited;
} graph_vertex_t;
/* Structure used to hold a graph edge information. */
typedef struct graph_edge
{
struct graph_vertex *adjac_vertex_p;
struct graph_edge *next_edge_p;
} graph_edge_t;
基本上,第一个结构用于存储顶点列表,而第二个结构用于第一个存储连接(边)。现在我正在尝试查看我找到的某个顶点的边列表并进行操作。我为此使用以下代码:
/* Find the right vertex to explore*/
for (curr_graph = start;
curr_graph != NULL && curr_graph->identifier != list[0];
curr_graph = curr_graph->next_vertex_p);
/* Explore all it's edges for new vertices. */
for (curr_edge_list = curr_graph->edge_list_p;
curr_edge_list != NULL;
curr_edge_list = curr_edge_list->next_edge_p)
{
printf("ID: %d ,", curr_edge_list->adjac_vertex_p->identifier);
/*do more stuff...*/
目前,我在使用 gdb 检查的 printf 上遇到了分段错误。我还检查了 curr_edge_list 、 curr_edge_list->adjac_vertex_p 和 curr_edge_list->adjac_vertex_p->identifier 的值:
Program received signal SIGSEGV, Segmentation fault.
0x0000555555554c9f in start_visit_graph_bf (start=0x7fffffffdee0,
starting_identifier=1) at explore_graph.c:170
170 printf("ID: %d ,", curr_edge_list->adjac_vertex_p->identifier);
(gdb) print curr_edge_list
$1 = (graph_edge_t *) 0x5555557574a0
(gdb) print curr_edge_list->adjac_vertex_p
$2 = (struct graph_vertex *) 0xfbad2488
(gdb) print curr_edge_list->adjac_vertex_p->identifier
Cannot access memory at address 0xfbad2488
(gdb)
我的第一反应是 0xfbad2488 的值是用来描述 NULL 的代码,所以我在 printf 语句之前检查了 curr_edge_list->adjac_vertex_p 不等于 NULL。此情况并非如此。因此我的问题是:值 0xfbad2488 是什么?如果变量具有该值,这意味着什么?还有哪些操作会导致这种行为?
【问题讨论】:
-
我的猜测是 curr_edge_list->adjac_vertex_p 没有初始化,你让 UB 试图访问它。
-
我的猜测在这里是一样的,虽然我不明白那会来自哪里。据我所知,我只在一个地方创建了 graph_edge_t 类型,并在那里初始化了 adjac_vertex_p
-
我对 0xfbad2488 进行了网络搜索。它是标准输入输出文件结构中常用的一组标志。在与 FILE * 变量相邻声明的变量中查找未初始化的变量以及越界数组访问。运行 valgrind 或使用 Address Sanitizer 编译可能会有所帮助。
标签: c segmentation-fault gdb