C -Segmentation fault !
It seems at least weird to me... The program runs normally.But after I call the enter() function for the 4th time,there is a segmentation fault!I would appreciate any help.
With the following function enter() I wanna add user commands' datas to a list.
[Some part of the code is already posted on another question of me, but I think I should post it again...as it's a different problem I'm facing now.]
/* struct for all the datas that user enters on file*/
typedef struct catalog
{ char short_name[50];
char surname[50];
signed int amount;
char description[1000];
struct catalog *next;
}catalog,*catalogPointer;
catalogPointer current;
catalogPointer head = NULL;
void enter(void) //user command: i <name> <surname> <amount> <description>
{
int n,j=2,k=0;
char temp[1500];
char *short_name,*surname,*description;
signed int amount;
char* params = strchr(command,' ') + 1; //strchr returns a pointer to the 1st space on the command.U want a pointer to the char right after that space.
strcpy(temp, params); //params is saved as temp.
char *curToken = strtok(temp," "); //strtok cuts 'temp' into strings between the spaces and saves them to 'curToken'
printf("temp is:%s \n",temp);
printf("\nWhat you entered for saving:\n");
for (n = 0; curToken; ++n) //until curToken ends:
{
if (curToken)
{ short_name = malloc(strlen(curToken) + 1);
strncpy(short_name, curToken, sizeof (short_name));
}
printf("S开发者_运维技巧hort Name: %s \n",short_name);
curToken = strtok(NULL," ");
if (curToken)
{ surname = malloc(strlen(curToken) + 1);
strncpy(surname, curToken,sizeof (surname)); }
printf("SurName: %s \n",surname);
curToken = strtok(NULL," ");
if (curToken)
{ //int * amount= malloc(sizeof (signed int *));
char *chk;
amount = (int) strtol(curToken, &chk, 10);
if (!isspace(*chk) && *chk != 0)
fprintf(stderr,"Warning: expected integer value for amount, received %s instead\n",curToken);
}
printf("Amount: %d \n",amount);
curToken = strtok(NULL,"\0");
if (curToken)
{ description = malloc(strlen(curToken) + 1);
strncpy(description, curToken, sizeof (description));
}
printf("Description: %s \n",description);
break;
}
if (findEntryExists(head, surname,short_name) != NULL) //call function in order to see if entry exists already on the catalog
printf("\nAn entry for <%s %s> is already in the catalog!\nNew entry not entered.\n",short_name,surname);
else
{
printf("\nTry to entry <%s %s %d %s> in the catalog list!\n",short_name,surname,amount,description);
newEntry(&head,short_name,surname,amount,description);
printf("\n**Entry done!**\n");
}
// Maintain the list in alphabetical order by surname.
}
catalogPointer findEntryExists (catalogPointer head, char num[],char first[])
{ catalogPointer p = head;
while (p != NULL && strcmp(p->surname, num) != 0 && strcmp(p->short_name,first) != 0)
{ p = p->next; }
return p;
}
catalogPointer newEntry (catalog** headRef,char short_name[], char surname[], signed int amount, char description[])
{
catalogPointer newNode = (catalogPointer)malloc(sizeof(catalog));
catalogPointer first;
catalogPointer second;
catalogPointer tmp;
first=head;
second=NULL;
strcpy(newNode->short_name, short_name);
strcpy(newNode->surname, surname);
newNode->amount=amount;
strcpy(newNode->description, description);
while (first!=NULL)
{ if (strcmp(surname,first->surname)>0)
second=first;
else if (strcmp(surname,first->surname)==0)
{
if (strcmp(short_name,first->short_name)>0)
second=first;
}
first=first->next;
}
if (second==NULL)
{ newNode->next=head;
head=newNode;
}
else //SEGMENTATION APPEARS WHEN IT GETS HERE!
{ tmp=second->next;
newNode->next=tmp;
first->next=newNode;
}
}
UPDATE: SegFault appears only when it gets on the 'else' loop of InsertSort() function. I observed that segmentation fault appears when i try to put on the list names that are after it. For example, if in the list exists:
[Name:b Surname:b Amount:6 Description:b] [Name:c Surname:c Amount:5 Description:c] [Name:d Surname:d Amount:4 Description:d] [Name:e Surname:e Amount:3 Description:e] [Name:g Surname:g Amount:2 Description:g] [Name:x Surname:x Amount:1 Description:x]
and i put: " x z 77 gege" there is a segmentation but if i put "x a 77 gege" it continues normally....
Can't post into comment, so here it goes:
while (first!=NULL) { //-> this loop can exit ONLY with 'first' being NULL
if (strcmp(surname,first->surname)>0)
second=first;
else if (strcmp(surname,first->surname)==0) {
if (strcmp(short_name,first->short_name)>0)
second=first;
}
first=first->next;
}
if (second==NULL) {
newNode->next=head;
head=newNode;
}
else {
tmp=second->next;
newNode->next=tmp;
first->next=newNode; // first used (but it's NULL!)
}
In other words, your program will crash if it finds any entry that satisfy conditions inside the loop and set 'second'. (This triggers intended addition "inside" the list).
Ok ~ no time to wait for answer :o), in a case you want to enter "after" the 'second' change code to this:
if (second==NULL) {
newNode->next=head;
head=newNode;
}
else {
newNode->next=second->next;
second->next=newNode;
}
explanation (S is 'second', N a 'newNode', A B just some exisiting entries in the list):
initial:
N
A -> S -> B
first assignment:
N ---\
|
v
A -> S -> B
second assignment:
N ---\
^ |
| v
A -> S B
and thus:
A-> S -> N -> B
Not sure what's causing the bug, but I did see this bad pattern:
char *short_name;
short_name = malloc(strlen(curToken) + 1);
strncpy(short_name, curToken, sizeof (short_name));
sizeof(short_name) will be always the same thing (usually 4 for 32 bit platforms and 8 for 64 bit platforms) so is not the correct value to use here. You should be doing:
strncpy(short_name, curToken, strlen(curToken) + 1);
Use something like valgrind to find problems like this.
Falling out of your while loop requires first to be null. In the else statement you attempt to access first.
加载中,请稍侯......
精彩评论