c - 使用 fscanf 时出现段错误,使用 valgrind 后调试麻烦

标签 c segmentation-fault valgrind

我删除了有效的代码,所以下面的代码不是整个程序,而是有问题的部分。

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

我从一个 CSV 文件中读入一个结构数组。

我的主要是这样的:

#include <stdio.h>
#include <stdlib.h>

main()
{
    menu();
}

然后是 menu.c :

#include <stdio.h>
#include <stdlib.h>
#include "DatabaseOps.h"
#include "menu.h"
#define SIZE 1000 //max size assumed to be 1000
void menu()
{
    int j, lastID; //keeping track of id numbers used

    Person* persons;
    persons = (Person*)malloc(SIZE * sizeof(Person)); /*declaring array of person structs on the heap*/

    for(j = 0; j < SIZE; j++) /*initialise all IDs to -1*/
        {
        persons[j].ID = -1;
        }

    int option = 1;
    while (option!=7)
    {
        printf("1. Load Database\n");
        scanf("%d", &option);

        switch (option)
            {
            case 1:
            printf("\nLoading Database\n\n");
            lastID = loadDb(persons);
            break;

            default:
            printf("Invalid choice, please try again\n\n");
            break;
            }
    }
} 

Persons 在 menu.h 中定义如下:

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

然后是导致错误的DatabaseOps.c文件:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "DatabaseOps.h"
#include "menu.h"

int loadDb(Person *inPersons)  //function reads csv file into an array of Employee structs
    {
    int i, newID = 0; /*declaring lastID counter to keep track of the last employee ID so that I can increment it when creating a new employee*/

    char* fileName = malloc( 100 * sizeof( char ));
    printf("Enter name of CSV file: ");
    scanf("%99s", fileName);

    FILE* f = fopen(fileName, "r");

    if(f==NULL)  /*If the file doesn't exist, return to menu*/
        {
        printf("Error: could not open file\n");
        }

    else
        { /*the fscanf function uses grouping by commas to seperate the CSV values - [^,]*/
        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; //Keeping track of the last used ID
            i++;
            }
        }
    fclose(f);

    return newID;
    }

Valgrind 给我这个错误,我不确定如何解释:

==19378== Use of uninitialised value of size 4
==19378==    at 0x405A215: _IO_vfscanf (in /lib/libc-2.12.so)
==19378==    by 0x4067368: __isoc99_fscanf (in /lib/libc-2.12.so)
==19378==    by 0x80486E5: loadDb (DatabaseOps.c:25)
==19378==    by 0x80485B5: menu (menu.c:29)
==19378==    by 0x804852E: main (main.c:6)
==19378== 
==19378== Invalid write of size 4
==19378==    at 0x405A215: _IO_vfscanf (in /lib/libc-2.12.so)
==19378==    by 0x4067368: __isoc99_fscanf (in /lib/libc-2.12.so)
==19378==    by 0x80486E5: loadDb (DatabaseOps.c:25)
==19378==    by 0x80485B5: menu (menu.c:29)
==19378==    by 0x804852E: main (main.c:6)
==19378==  Address 0x9acac288 is not stack'd, malloc'd or (recently) free'd
==19378== 
==19378== 
==19378== Process terminating with default action of signal 11 (SIGSEGV)
==19378==  Access not within mapped region at address 0x9ACAC288
==19378==    at 0x405A215: _IO_vfscanf (in /lib/libc-2.12.so)
==19378==    by 0x4067368: __isoc99_fscanf (in /lib/libc-2.12.so)
==19378==    by 0x80486E5: loadDb (DatabaseOps.c:25)
==19378==    by 0x80485B5: menu (menu.c:29)
==19378==    by 0x804852E: main (main.c:6)

最佳答案

int i, newID = 0; /*declaring lastID counter to keep track of the last employee ID so that I can increment it when creating a new employee*/

i需要初始化为0。

关于c - 使用 fscanf 时出现段错误,使用 valgrind 后调试麻烦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18972245/

相关文章:

c - 如果我重复运行这个程序,为什么在 seg-fault 之前打印的最后一个数字会有所不同?

c++ - 使用 gdb 检查对象时得到不同的值

c - mmap 和 valgrind,mmap 不会增加堆大小

c - 使用 --trace-children 和 execl() 时保留 valgrind 日志文件中的内容

c - 为什么我的变量没有初始化?

c - gtk+3 回调中乘法后的错误和随机结果

c - 是否允许全局静态标识符以单个 _ 开头?

c - 为什么这段代码会导致段错误错误?

c - c中的链接字符串列表

使用按位运算符比较 float