我在下面的fscanf行上遇到了分段错误。我为每个变量添加了字符宽度以尝试对其进行修复,因此我不明白为什么它会出现段错误。

我从CSV文件读取了一个结构数组。

结构为:

typedef struct Person
    {
    int ID;
    int salary;
    int deleted;
    char salutation[4];
    char firstName[21];
    char surName[31];
    char job[16];
    } Person;


我声明了结构数组:

Person* persons;
persons = (Person*)malloc(SIZE * sizeof(Person));


然后使用以下while循环将CSV文件读入以下值:

(我初始化为0)

while(fscanf(f, "%d,%3[^,],%20[^,],%30[^,],%15[^,],%d,%d", &inPersons[i].ID, inPersons[i].salutation, inPersons[i].firstName, inPersons[i].surName, inPersons[i].job, &inPersons[i].salary, &inPersons[i].deleted)!=EOF)
            {
            newID = inPersons[i].ID;
            i++;
            }


段故障在fscanf语句期间发生。我没有使用valgrind的经验,但是对于该行它给了我这个错误:

==16810== Invalid write of size 4
==16810==    at 0x578215: _IO_vfscanf (in /lib/libc-2.12.so)
==16810==    by 0x585368: __isoc99_fscanf (in /lib/libc-2.12.so)
==16810==    by 0x8048951: loadDb (Database.c:23)
==16810==    by 0x8048711: menu (Menu.c:37)
==16810==    by 0x804861E: main (main.c:6)
==16810==  Address 0x27230128 is not stack'd, malloc'd or (recently) free'd


我也在同一行中得到了这些Valgrind错误:

==18457== Use of uninitialised value of size 4
==18457==    at 0x405A215: _IO_vfscanf (in /lib/libc-2.12.so)
==18457==    by 0x4067368: __isoc99_fscanf (in /lib/libc-2.12.so)
==18457==    by 0x8048943: loadDb (Database.c:23)
==18457==    by 0x8048711: menu (Menu.c:37)
==18457==    by 0x804861E: main (main.c:6)


==18457== Process terminating with default action of signal 11 (SIGSEGV)
==18457==  Access not within mapped region at address 0x5C5E4128
==18457==    at 0x405A215: _IO_vfscanf (in /lib/libc-2.12.so)
==18457==    by 0x4067368: __isoc99_fscanf (in /lib/libc-2.12.so)
==18457==    by 0x8048943: loadDb (Database.c:23)
==18457==    by 0x8048711: menu (Menu.c:37)
==18457==    by 0x804861E: main (main.c:6)

最佳答案

如果您在字母或标点符号处应该有一个数字,则表示存在无限循环,并且溢出了所分配人员的范围。您应该检查:

while (i < SIZE && (num = fscanf(f, "...", ...)) == 7)
{
    ...process valid input...
}
...consider what to do here, using `num` to distinguish between EOF and failed conversions...


valgrind无法识别内存的事实令人困惑。您已经采取了大多数相关步骤来确保不会发生缓冲区溢出(所有步骤都必须正确检查fscanf()的状态,否则除外)。

哦...您分配了persons;您正在阅读inPersons ...这是正确的吗?

我想我会写一个函数来调用fscanf()并检测并报告错误,然后从while循环中调用它:

while (i < SIZE && get_person(&persons[i]) != EOF)
   ...


要么:

while (i < SIZE && get_person(&inPersons[i]) != EOF)
   ...


这也允许您从fscanf()切换到fgets()sscanf()getline()sscanf()

关于c - 使用fscanf时无法调试seg错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18971793/

10-16 01:03