我试图在这里找到问题 - 在这个函数中:
void PrintDic(dictionary **head)
{
dictionary *current = *head;
if(current->nexdic==NULL)
printf("empty dictionary\n");
else
{
while(current->nexdic!=NULL)
{
int i;
for(i=0;i<1; i++)
printf("%s\n",current->word);
current=current->nexdic;
}
}
}
在Visual Studio中它可以工作,但在Linux中它总是给我一个分段错误。
结构:
struct dictionary
{
char word[MAXLETTERS];
char** year;
int countyear;
char** synonyms;
int countsyn;
char** def;
int countdef;
struct dictionary*nexdic;
};
添加功能:(将值插入结构并以字典方式查找地点以添加struct =链接列表!)
void Add(char* word, char * year,int countyear, char*syn, int countsyn, char* def,int countdef, dictionary** head)
{
dictionary*next;
//add new entry
dictionary*newentry=(dictionary*)malloc(sizeof(dictionary));
if(CheckNull(newentry)==1)
exit(1);
int i;
char *index;
//insert word
strcpy(newentry->word,word);
//insert year
char **toyear=(char **)malloc((countyear+1)*sizeof(char*));
index=year;
for(i=0;i<=countyear; i++)
{
toyear[i]=index;
index=NextString(index);
}
newentry->year=toyear;
//insert syn
index=syn;
char **tosyn=(char **)malloc((countsyn+1)*sizeof(char*));
for(i=0;i<=countsyn; i++)
{
tosyn[i]=index;
index=NextString(index);
}
newentry->synonyms=tosyn;
//insert definition
index=def;
char **todef=(char **)malloc((countdef+1)*sizeof(char*));
for(i=0;i<=countdef; i++)
{
todef[i]=index;
index=NextString(index);
}
newentry->def=todef;
//set counts
newentry->countyear=countyear+1;
newentry->countsyn=countsyn+1;
newentry->countdef=countdef+1;
next=FindPlace(newentry->word,*head);
if(next==NULL)
{
if(*head==NULL)
newentry->nexdic=NULL;
else
{
newentry->nexdic=*head;
}
*head=newentry;
}
else
{
newentry->nexdic=next->nexdic;
next->nexdic=newentry;
}
}
答案 0 :(得分:0)
下面的代码问题。
在while循环中,您的current
变为current->nexic
,但这不能NULL
。对于下一次迭代,同时尝试访问您的current
(current->nexdic
)NULL
,从而导致段错误。
while(current->nexdic!=NULL)
{
int i;
for(i=0;i<current->countdef; i++)
printf("%s\n",current->def[i]);
current=current->nexdic;
}
我不知道你的程序逻辑,但你可以检查while(current != NULL)
而不是current->nexdic
答案 1 :(得分:0)
此代码似乎有效(在Mac OS X 10.9.1上使用GCC 4.8.2进行测试):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { MAXLETTERS = 32 };
typedef struct dictionary
{
char word[MAXLETTERS];
char **year;
char **synonyms;
char **def;
int countyear;
int countsyn;
int countdef;
struct dictionary *nexdic;
} dictionary;
static void PrintDic(dictionary **head)
{
dictionary *current = *head;
while (current != NULL)
{
printf("%s\n", current->word);
current = current->nexdic;
}
}
static int CheckNull(dictionary *dict)
{
return dict == 0;
}
static char *NextString(char *str)
{
return strchr(str, ',');
}
static dictionary *FindPlace(char *word, dictionary *head)
{
printf("FP: (%p) [%s]\n", (void *)head, word);
dictionary *ohead = 0;
while (head != 0 && printf("HW: (%p) [%s]\n", head, head->word) > 0 && strcmp(head->word, word) < 0)
{
ohead = head;
head = head->nexdic;
}
printf("FP: (%p)\n", (void *)ohead);
return ohead;
}
static void Add(char *word, char *year, int countyear, char *syn, int countsyn,
char *def, int countdef, dictionary **head)
{
// Create new entry
// add new entry
dictionary *newentry = (dictionary *)malloc(sizeof(dictionary));
if (CheckNull(newentry) == 1)
exit(1);
int i;
char *index;
// insert word
strcpy(newentry->word, word);
// insert year
char **toyear = (char **)malloc((countyear + 1) * sizeof(char *));
index = year;
for (i = 0; i <= countyear; i++)
{
toyear[i] = index;
index = NextString(index);
}
newentry->year = toyear;
// insert syn
index = syn;
char **tosyn = (char **)malloc((countsyn + 1) * sizeof(char *));
for (i = 0; i <= countsyn; i++)
{
tosyn[i] = index;
index = NextString(index);
}
newentry->synonyms = tosyn;
// insert definition
index = def;
char **todef = (char **)malloc((countdef + 1) * sizeof(char *));
for (i = 0; i <= countdef; i++)
{
todef[i] = index;
index = NextString(index);
}
newentry->def = todef;
// set counts
newentry->countyear = countyear + 1;
newentry->countsyn = countsyn + 1;
newentry->countdef = countdef + 1;
// Insert new entry in correct place
dictionary *next = FindPlace(newentry->word, *head);
printf("Next = %p; head = %p\n", (void *)next, (void *)*head);
if (next == NULL)
{
printf("-1-\n");
newentry->nexdic = *head;
*head = newentry;
}
else
{
printf("-2-\n");
newentry->nexdic = next->nexdic;
next->nexdic = newentry;
}
}
int main(void)
{
char line[4096];
dictionary *head = 0;
while (fgets(line, sizeof(line), stdin) != 0)
{
size_t offset = 0;
char word[4096];
int nchars;
line[strlen(line)-1] = '\0';
printf("Line: [%s]\n", line);
while (sscanf(line + offset, "%s%n", word, &nchars) == 1)
{
printf("Word: [%s]\n", word);
char *years = "1990,1999";
char *syns = "a,z";
char *defs = "definition1,definition2";
printf("Old Head = %p\n", head);
Add(word, years, 2, syns, 2, defs, 2, &head);
PrintDic(&head);
printf("New Head = %p\n", head);
offset += nchars;
}
}
return 0;
}
除了编写缺少的函数,如FindPlace()
,CheckNull()
和NextString()
(以及测试驱动程序main()
),并定义FindPlace()
返回NULL当新节点应该位于列表的头部时,否则应该在返回的节点指针之后立即插入新节点,主要更改是处理“在头部插入”的代码,该代码比它需要的更复杂成为。 for
中有一个有趣的单周期PrintDic()
循环,现在已不复存在。您通过包括年份,同义词和定义信息使这个过程对我们感到不舒服,这可能对手头的问题不重要。司机会做最简单的事情。请注意,它不会将传递给Add()
的字符串拆分,因此第一年条目会打印所有内容,第二年打印除第一年之外的所有字符串,依此类推,同样适用于同义词和定义。在每种情况下,列表项以逗号分隔。
有大量的调试打印代码;欢迎你删除它。
示例输出:
ggg
Line: [ggg]
Word: [ggg]
Old Head = 0x0
FP: (0x0) [ggg]
FP: (0x0)
Next = 0x0; head = 0x0
-1-
ggg
New Head = 0x7f848bc038b0
fff
Line: [fff]
Word: [fff]
Old Head = 0x7f848bc038b0
FP: (0x7f848bc038b0) [fff]
HW: (0x7f848bc038b0) [ggg]
FP: (0x0)
Next = 0x0; head = 0x7f848bc038b0
-1-
fff
ggg
New Head = 0x7f848bc03960
ccc
Line: [ccc]
Word: [ccc]
Old Head = 0x7f848bc03960
FP: (0x7f848bc03960) [ccc]
HW: (0x7f848bc03960) [fff]
FP: (0x0)
Next = 0x0; head = 0x7f848bc03960
-1-
ccc
fff
ggg
New Head = 0x7f848bd00000
ddd
Line: [ddd]
Word: [ddd]
Old Head = 0x7f848bd00000
FP: (0x7f848bd00000) [ddd]
HW: (0x7f848bd00000) [ccc]
HW: (0x7f848bc03960) [fff]
FP: (0x7f848bd00000)
Next = 0x7f848bd00000; head = 0x7f848bd00000
-2-
ccc
ddd
fff
ggg
New Head = 0x7f848bd00000
eee
Line: [eee]
Word: [eee]
Old Head = 0x7f848bd00000
FP: (0x7f848bd00000) [eee]
HW: (0x7f848bd00000) [ccc]
HW: (0x7f848be00000) [ddd]
HW: (0x7f848bc03960) [fff]
FP: (0x7f848be00000)
Next = 0x7f848be00000; head = 0x7f848bd00000
-2-
ccc
ddd
eee
fff
ggg
New Head = 0x7f848bd00000
aaa
Line: [aaa]
Word: [aaa]
Old Head = 0x7f848bd00000
FP: (0x7f848bd00000) [aaa]
HW: (0x7f848bd00000) [ccc]
FP: (0x0)
Next = 0x0; head = 0x7f848bd00000
-1-
aaa
ccc
ddd
eee
fff
ggg
New Head = 0x7f848be000b0
bbb
Line: [bbb]
Word: [bbb]
Old Head = 0x7f848be000b0
FP: (0x7f848be000b0) [bbb]
HW: (0x7f848be000b0) [aaa]
HW: (0x7f848bd00000) [ccc]
FP: (0x7f848be000b0)
Next = 0x7f848be000b0; head = 0x7f848be000b0
-2-
aaa
bbb
ccc
ddd
eee
fff
ggg
New Head = 0x7f848be000b0
zzz
Line: [zzz]
Word: [zzz]
Old Head = 0x7f848be000b0
FP: (0x7f848be000b0) [zzz]
HW: (0x7f848be000b0) [aaa]
HW: (0x7f848bc03a10) [bbb]
HW: (0x7f848bd00000) [ccc]
HW: (0x7f848be00000) [ddd]
HW: (0x7f848bf00000) [eee]
HW: (0x7f848bc03960) [fff]
HW: (0x7f848bc038b0) [ggg]
FP: (0x7f848bc038b0)
Next = 0x7f848bc038b0; head = 0x7f848be000b0
-2-
aaa
bbb
ccc
ddd
eee
fff
ggg
zzz
New Head = 0x7f848be000b0