C:带有strcpy的分段错误

时间:2017-05-05 15:55:54

标签: c string segmentation-fault malloc

我想知道是否有人可以帮助我解决这个分段错误,valgrind和gdb指向strcpy(),但我仍然无法找到它..

void listusers(userstat* ptustat)
{
    FILE* fileu = openfile("user_db");
    char* str = (char*) malloc(sizeof(char)*100);
    char* temp = (char*) malloc(sizeof(char)*100);
    int i = 0;
    int offset = 0;
    while (fgets(str,100,fileu) != NULL)
        {   
            strcpy(temp,str);
            strcpy((*(ptustat+i)).name,strtok(temp,"#"));
            offset+=(strlen(temp)+1);
            strcpy(temp,str+offset);
            strcpy((*(ptustat+i)).contact,strtok(temp,"#"));
            offset+=(strlen(temp)+1);
            strcpy(temp,str+offset);
            strcpy((*(ptustat+i)).uname,strtok(temp,"#"));
            offset+=(strlen(temp)+1);
            strcpy(temp,str+offset);
            strtok(temp,"#");
            offset+=(strlen(temp)+1);
            strcpy(temp,str+offset);
            (*(ptustat+i)).saldo = atof(strtok(temp,"\n"));
            i++;
        }
closefile(fileu);
free(str);free(temp);
}

userstat definiton:

typedef struct userstat {
char name[50];
char contact[50];
char uname[50];
float saldo;
} userstat;

它正在读取的文件也有这样的行: 名#接触#用户名#密码#钱

gdb backtrace:

    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: Ficheiro ou directoria inexistente.
(gdb) bt
#0  __strcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:296
#1  0x00000000004030b2 in listusers ()
#2  0x0000000000401fee in statsmenu ()
#3  0x0000000000401c1d in menuinit ()
#4  0x0000000000400ecc in main ()
(gdb) 

调用函数和分配struct:

void statsmenu()
    {

        char x = '0';

        getchar(); 
        while (1)
            {
                prodstat db[100] = {{"",0.00,0.00,0.00}};
                prodstat *ptstat = db;
                userstat dbu[100] = {{"","","",0.00}};
                userstat *ptustat = dbu;
                listproducts(ptstat);
                listusers(ptustat);

1 个答案:

答案 0 :(得分:2)

我用等效(但可读)(*ptustat + i)).xxx替换了笨拙的ptustat[i].xxx

现在你对strtok的使用是错误和尴尬的。试试这个:

while (fgets(str, 100, fileu) != NULL)
{
    strcpy(temp, str);
    strcpy(ptustat[i].name, strtok(temp, "#"));
    offset += (strlen(temp) + 1);
    strcpy(temp, str + offset);
    char *p = strtok(temp, "#");

    if (p == NULL)   // p can be NULL here
    {
        printf("BUMMER\n");
        exit(1);
    }

    strcpy(ptustat[i].contact, p);
    offset += (strlen(temp) + 1);
    strcpy(temp, str + offset);
    strcpy(ptustat[i].uname, strtok(temp, "#"));
    offset += (strlen(temp) + 1);
    strcpy(temp, str + offset);
    strtok(temp, "#");
    offset += (strlen(temp) + 1);
    strcpy(temp, str + offset);
    ptustat[i].saldo = atof(strtok(temp, "\n"));
    i++;
}

我将错误的纠正作为练习。

此外(与您的问题无关):

您可以替换

char* str = (char*) malloc(sizeof(char)*100);
...
free(str);

通过

char str[100];

动态分配固定空间缓冲区通常毫无意义。