我正在尝试在C中设置相邻的列表数组:
mygraph->table = (Node *)malloc(MaxSize * sizeof(Node));
check(mygraph->table, error);
int i;
for(i = 1; i <= MaxSize; i++)
{
mygraph->table[i].name = NULL;
mygraph->table[i].outlist = NULL;
mygraph->table[i].outdegree = 0;
}
...
当我运行此代码时,它工作正常。但是当我尝试访问表中的索引时,我得到了一个分段错误:
mygraph->table[n].name = name;
我检查了n
索引,这是正确的。 MaxSize
为10,但即使n
= 1。
编辑:
typedef struct linkedlist { // linked list of ints (for use in Node)
int index;
struct linkedlist *next;
} List;
typedef struct { // a Node of a Graph
char *name;
List *outlist; // adjacency list
int outdegree; // length of outlist
//double pagerank_score; //not needed for this exercise
} Node;
typedef struct {
// your code goes here
int MaxSize; /*Maximum number of vertices that the graph can constain*/
Node *table; /*Adjacency lists' array*/
} Graph;
答案 0 :(得分:2)
即使在
n = 1
时,我也会遇到细分错误。
这是因为您的代码具有未定义的行为。它写过数组的结尾:
for(i = 1; i <= MaxSize; i++) // should be i=0 ; i<MaxSize
当n
为10
时,代码不会在您的系统上崩溃 - 可能是因为malloc
在块的末尾添加了足够的填充以容纳超过结尾的额外元素数组,但错误仍然存在。
您可以使用内存分析器找到此类隐藏的错误,例如: valgrind
修复是在初始化中使用正确的索引:
for(int i = 0 ; i != MaxSize ; i++) {
}
答案 1 :(得分:1)
这是关键:
mygraph->table[n].name = name;
没有提及为name
变量分配内存。
另外,在表达式的右侧分配name
变量,最好通过strncpy
或strdup
来表明您的意图。
你有责任确保你确实free
name
成员占用的内存。
答案 2 :(得分:1)
您的循环需要从0
运行到MaxSize-1
,如下所示:
for(i = 0; i < MaxSize; i++)
{
mygraph->table[i].name = NULL;
mygraph->table[i].outlist = NULL;
mygraph->table[i].outdegree = 0;
}
所以第一个元素位于mygraph->table[0]
,最后一个元素位于<mygraph->table[MaxSize-1]
。
在指针算术中,第一个元素将从mygraph->table
开始,最后一个元素将开始:
((mygraph->table) + MaxSize-1)
并结束:
((mygraph->table) + MaxSize)
table[MaxSize]
等效于*((mygraph->table) + MaxSize)
,这超出了数组边界。