Reputation: 1168
I am trying to find the problem here - in this function:
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;
}
}
}
In Visual Studio it works, but in Linux it always gives me a segmentation fault.
The struct:
struct dictionary
{
char word[MAXLETTERS];
char** year;
int countyear;
char** synonyms;
int countsyn;
char** def;
int countdef;
struct dictionary*nexdic;
};
The add function: (Insert the values to the struct and find place in lexicographic way to add the struct = linked list!)
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;
}
}
Upvotes: 1
Views: 272
Reputation: 755064
This code seems to work (tested on Mac OS X 10.9.1 with 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;
}
Apart from writing the missing functions like FindPlace()
, CheckNull()
and NextString()
(and a test driver, main()
), and defining that FindPlace()
returns NULL when the new node should be at the head of the list and otherwise the new node should be inserted immediately after the node pointer that is returned, the main changes were to the code that handles 'insert at head' which was more complex than it needed to be. There was a funny one-cycle for
loop in PrintDic()
which is no more. You made the process uncomfortable for us by including the years, synonyms and definitions information, which was probably not material to the problem at hand. The driver does about the simplest thing possible with those. Note that it does not split the strings passed into Add()
, so the first year entry prints everything, the second prints all but the first, and so on, and similarly for the synonyms and definitions. In each case, the list items are separated by commas.
There's swathes of debug printing code in place; you're welcome to remove it.
Sample output:
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
Upvotes: 0
Reputation: 4758
Problem with code below.
In while loop, your current
become current->nexic
, this could not NULL
. For next iteration while try to access your current
(current->nexdic
) which is NULL
and hence segment fault.
while(current->nexdic!=NULL)
{
int i;
for(i=0;i<current->countdef; i++)
printf("%s\n",current->def[i]);
current=current->nexdic;
}
I don't know your logic of program, but you can check while(current != NULL)
instead of current->nexdic
Upvotes: 1