【发布时间】:2015-01-03 20:57:59
【问题描述】:
我正在尝试更改二进制文件中的一些信息,但出现分段错误。我一直在尝试处理它几个小时。假设有两个名称相同的团队。名字想改。但是,我得到分段错误。 (问题)假设有两个名称相同的团队。名字想改。但是,我遇到了分段错误。感谢所有感谢的答案。
team_name, city , stadium ,fdate, colors
the team is in binary file
manunited,manchester,old_trafford,1878,black-rd
chelsea,london,stamford_bridge,1905,blue-whte
manunited,manchester,old_trafford,1878,black-rd
----------------------------------------
example input
update
update team_name=newcastle,founding_date=2014 in teams where team_name=manunited
----------------------------------------
output
**segmentation fault**
----------------------------------------
new output teams.bin should be
newcastle,manchester,old_trafford,2014,black-rd
chelsea,london,stamford_bridge,1905,blue-whte
newcastle,manchester,old_trafford,2014,black-rd
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
int main()
{
char read_command[12];
/* checking insert */
char str1[100],str2[5],str3[18],space,str4[100];
scanf("%s", read_command);
if(strcmp(read_command,"update") == 0)
{
scanf("%s",str3);//read update from input code
//printf("\nstr3=%s",str3);
scanf("%s",str4);
//printf("\nstr4=%s",str4);
scanf("%c",&space);
fgets(str1,100,stdin);
//printf("\nstr1=%s",str1);
updatefunc(str1,str4);
}
return 0;
}
void wherefunc(char *str,char *tag,char *id)
{
char *token;
int i=0;
token = strtok(str,"=");
strcpy(tag,token);
token = strtok(NULL,"=");
strcpy(id,token);
}
void updatefunc(char *str1, char *str2)
{
FILE *fp;
char tag[30]; // regard to the input it is team_name
char id[30]; // regard to the input it is manunited
/* regard to the input it will change first team_name then founding_date */
char variablenew[30];
/* regard to the input it will change first newcastle then 2014 */
char valuenew[30];
char *tokenstr1;
char *tokenstrnew;
char *buff;
buff = (char*) malloc(strlen(str1) + 1);
strcpy(buff,str1);
char *token;
const char space[2] = " ";
const char comma[2] = ",";
char tempstrs[10][100];
char tempstrsnew[10][30];
int i = 0, j = 0 ,c, ii;
tokenstrnew = strtok(str2,comma);
while (tokenstrnew != NULL)
{
//printf(" %s %d \n",tokenstr1,i);
strcpy(tempstrsnew[j],tokenstrnew);
j++;
tokenstrnew = strtok(NULL,comma);
}
//printf("%d %s %s",j,tempstrsnew[0],tempstrsnew[1]);
tokenstr1 = strtok(buff,space);
while (tokenstr1 != NULL)
{
/* get rid of \n character bcz of fgets() */
int len = strlen(tokenstr1);
if (len > 0 && tokenstr1[len-1] == '\n') tokenstr1[len-1] = '\0';
//printf(" %s %d \n",tokenstr1,i);
strcpy(tempstrs[i],tokenstr1);
i++;
tokenstr1 = strtok(NULL,space);
}
wherefunc(tempstrs[3],tag,id); //every wherefunc to seperate "=" symbols
//printf("\n\ntag = %s id = %s",tag,id);
//printf("\n\n%s",str2);
if(strcmp(tempstrs[1],"teams") == 0)
{
fp=fopen("teams.bin", "rb+");
if (!fp)
{
printf("Unable to open file %s", "teams.bin");
exit(1);
}
teams *t;
t=(teams*)malloc(sizeof(teams)*1000);
int x = fread(t, sizeof(teams), 1000, fp);
t = (teams*)realloc(t,x*sizeof(teams));
for( ii = 0 ; ii < x ; ii++)
{
if((strcmp(tag,"team_name") == 0) && (strcmp(id,t[ii].team_name) == 0))
{
fread(&t[ii], sizeof(teams), 1, fp);
for(c = 0 ; c < j ; c++)
{
wherefunc(tempstrsnew[c],variablenew,valuenew);
if(strcmp(variablenew,"team_name") == 0)
{
strcpy(t[ii].team_name,valuenew);
fseek(fp, ii*sizeof(team), SEEK_SET);
fwrite(&t[ii], sizeof(teams), 1, fp);
}
else if(strcmp(variablenew,"founding_date") == 0)
{
t[ii].founding_date = atoi(valuenew) ;
fseek(fp, ii*sizeof(team), SEEK_SET);
fwrite(&t[ii], sizeof(teams), 1, fp);
}
}
}
}
}
}
gdb 结果:
(gdb) run
Starting program: /home/soner/Desktop/folder/a.out
update
update team_name=newcastle,founding_date=2014 in teams where team_name=manunited
Program received signal SIGSEGV, Segmentation fault.
__strcpy_sse2_unaligned ()
at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:296
296 ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S: No such file or directory.
(gdb) backtrace
#0 __strcpy_sse2_unaligned ()
at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:296
#1 0x000000000040fa91 in wherefunc (str=0x7fffffffd7a0 "team_name",
tag=0x7fffffffdbd0 "team_name", id=0x7fffffffdbf0 "2014") at seg.c:2321
#2 0x00000000004125b8 in updatefunc (
str1=0x7fffffffdc90 "in teams where team_name=manunited\n",
str2=0x7fffffffdd00 "team_name=newcastle") at seg.c:3357
#3 0x000000000040109a in main () at seg.c:70
(gdb) frame 1
#1 0x000000000040fa91 in wherefunc (str=0x7fffffffd7a0 "team_name",
tag=0x7fffffffdbd0 "team_name", id=0x7fffffffdbf0 "2014") at seg.c:2321
2321 strcpy(id,token);
(gdb) frame 2
#2 0x00000000004125b8 in updatefunc (
str1=0x7fffffffdc90 "in teams where team_name=manunited\n",
str2=0x7fffffffdd00 "team_name=newcastle") at seg.c:3357
3357 wherefunc(tempstrsnew[c],variablenew,valuenew);
(gdb) frame 3
#3 0x000000000040109a in main () at seg.c:70
70 updatefunc(str1,str4);
(gdb)
【问题讨论】:
-
不要强制转换
malloc并检查返回的指针是否为NULL,也不要执行t = realloc(t, newsize),因为如果它失败,将无法访问free(t)。另外,修复你的代码缩进真的很难遵循,也许你需要更多的功能。
标签: c file-io segmentation-fault malloc binaryfiles