C 段错误!
这至少对我来说很奇怪......程序运行正常。但是在我第四次调用 Enter() 函数后,出现分段错误!我将不胜感激。
通过以下函数 Enter() 我想将用户命令的数据添加到列表中。
[代码的某些部分已经发布在我的另一个问题上,但我认为我应该再次发布它......因为这是我现在面临的另一个问题。]
/* 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("Short 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;
}
}
更新: SegFault 仅当进入 InsertSort() 函数的“else”循环时才会出现。 我观察到,当我尝试添加后面的列表名称时,会出现分段错误。 例如,如果列表中存在:
[姓名:b 姓氏:b 金额:6 描述:b] [姓名:c 姓氏:c 金额:5 描述:c] [姓名:d 姓氏:d 数量:4 描述:d] [姓名:e 姓氏:e 金额:3 描述:e] [姓名:g 姓氏:g 数量:2 描述:g] [姓名:x 姓氏:x 金额:1 描述:x]
我输入:“xz 77 gege”有一个分段 但如果我输入“xa 77 gege”,它会正常继续......
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("Short 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....
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
无法发表评论,所以这里是:
换句话说,如果您的程序找到任何满足循环内条件并设置“第二”的条目,它将崩溃。 (这会触发列表“内部”的预期添加)。
好的〜没有时间等待答案:o),如果您想在“第二个”之后输入,请将代码更改为:
解释(S 是“第二个”,N 是“newNode”,AB 只是一些现有条目在列表中):
Can't post into comment, so here it goes:
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:
explanation (S is 'second', N a 'newNode', A B just some exisiting entries in the list):
不确定是什么导致了这个错误,但我确实看到了这个错误的模式:
sizeof(short_name)
将始终是相同的东西(通常 32 位平台为 4,64 位平台为 8),所以不是此处使用的正确值。你应该这样做:Not sure what's causing the bug, but I did see this bad pattern:
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:使用诸如 valgrind 之类的东西来查找此类问题。
Use something like valgrind to find problems like this.
退出 while 循环需要首先为空。在 else 语句中,您首先尝试访问。
Falling out of your while loop requires first to be null. In the else statement you attempt to access first.