【问题标题】:C: Segmentation Fault with strcpyC:使用 strcpy 的分段错误
【发布时间】:2017-05-05 15:55:54
【问题描述】:

我想知道是否有人可以帮助我解决这个分段错误,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);
}

用户统计定义:

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

它正在读取的文件也有这样的行: 姓名#联系人#用户名#密码#钱

gdb 回溯:

    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) 

函数的调用和结构体的分配:

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);

【问题讨论】:

  • 请至少说明userstat的定义,并说明您如何称呼listusers,问题的根源最接近那里。
  • @MichaelWalz:考虑到strtok() 的不正确或至少不寻常的使用,我不确定这是“最有可能”的问题。
  • 请说明您如何调用listusers 以及您如何声明/分配传递给此函数的参数。
  • 在打开调试的情况下编译你的代码(gcc 中的 -g 选项),然后 gdb 会告诉你 listusers 中的哪一行你遇到了问题

标签: c string segmentation-fault malloc


【解决方案1】:

我将尴尬的 (*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];

动态分配固定空间缓冲区通常是没有意义的。

【讨论】:

  • 感谢您的帮助,但我通过删除所有这些 strtok 语句并用单个 sscanf() 替换来修复了该错误。
猜你喜欢
  • 2014-10-21
  • 2013-02-23
  • 2016-02-24
  • 1970-01-01
  • 1970-01-01
  • 2015-02-28
  • 1970-01-01
  • 1970-01-01
  • 2018-02-07
相关资源
最近更新 更多