【问题标题】:fopen does not work properly and I get segmentation fault when I use fclosefopen 无法正常工作,使用 fclose 时出现分段错误
【发布时间】:2015-06-26 01:23:10
【问题描述】:

我是新的 c 程序员。我正在编写一个小型学生数据库。我有一个结构数组,我想将其写入文件。到目前为止,该程序运行良好。我可以打印出保存在名为 db(数据库的缩写)的数组中的数据。为了能够写入数据,我打开了一个新的 c 文件,并编写了一个方法writeData(),它允许我使用FILE-objectfopen 写入数据。以下是位于头文件中的数据库的方法:

//header file
#ifndef DB_OPS
#define DB_OPS
#define SIZE 3typedef int bool;
typedef int bool;
#define true 1
#define false 0
struct student{
    bool statusFlag;
    char lastname[20];
    char firstname[20];
    int  mNr;
    char subject[30];
    char nationality[20];
};

int createDb(int s);
struct student getData(char * lastname, char * firstname, int matNr, char * courseOfStudy, char * nationality);
void insert_student(struct student *  st);
void update_student(int matNr);
bool delete_student(int matNr);
void display_result(bool  res, bool operation);
bool search_student(int matNr);
void display_db();
void writeData();//method to write data
void readData();
void print();
#endif

然后我定义了方法writeData()。代码如下:

//a c-file
#include <stdlib.h>
#include <stdio.h>
#include "db_ops.h"


void writeData(){
    //when i use fopen, the data saved in db will be damaged
    FILE * fpw;
    fpw=fopen("database.txt","wb");
    if(fpw==NULL){
        printf("the file cannot be opened");
        exit(1);
    }

    extern struct student *db;
    int i;
    for(i=0;i<SIZE;i++){
        printf("%s, %s, %d, %s , %s\n", 
            (db+i)->lastname,(db+i)->firstname,(db+i)->mNr, (db+i)->subject, (db+i)->nationality);
    }
    fclose(fpw);//When I use fclose(),I get segmentation fault: free(): invalid next size
}

到目前为止,我无法找到该问题的解决方案或解释。当我使用 fopen 时,我再也找不到保存在数组 db 中的数据了。我确实知道作为指针的数组 db 是否指向数组外部。第二个问题在于使用 fclose,它会产生分段错误。有什么建议吗? 这是位于我初始化数组 db 的文件中的一段代码:

// another c-file
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "db_ops.h"

struct student * db;
struct student * ptrDb;
static int insertCounter=1;
int size=0;
int   createDb(int s){
    size=s;
    db= (struct student *)calloc(3,sizeof(struct student *));
    if(db==NULL){
        printf("dynamic allocation failed");
        return EXIT_FAILURE;
    }
    ptrDb=db;
    printf("database was created\n");
}
struct student getData(char * lastname, char * firstname, int matNr, char * subject, char * nationality){
    struct student st;
    int i;
    if(insertCounter<=size){
        //get data
        st.statusFlag=1;//flag to show, whether the program gets data or not 
        //0-byte marks the end of the string
        memcpy(st.lastname,lastname,strlen(lastname)+1);
        memcpy(st.firstname,firstname,strlen(firstname)+1);
        st.mNr=matNr;
        memcpy(st.subject, subject,strlen(subject)+1);
        memcpy(st.nationality,nationality,strlen(nationality)+1);
        //printf("%s,%s,%d,%s,%s\n",st.lastname,st.firstname,st.mNr,st.subject,st.nationality);
        return st;
    }else if(insertCounter>size){
        st.statusFlag=0;
        return st;
   }
}
//coping input by reference
void insert_student(struct student *  st){

    printf("statusFlag:%d\n",st->statusFlag);
    if(st->statusFlag==1){  
        *ptrDb=*st;
        insertCounter++;
        ptrDb++;    
    }else{  
          printf("##########################################################\n");
    printf("no insert is possible, The maximum size has been reached\n");
       printf("##########################################################\n");
}

}

【问题讨论】:

  • 由于我们不知道您从哪里获得/创建您的db 指针,因此我们无法确定您的操作是对还是错。请创建尽可能小的代码以充分显示您在做什么。
  • 来自 fopen 的手册页 w Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file. 因此,要保留现有内容,请使用 w+。要写入binary 数据,请使用wb+ man7.org/linux/man-pages/man3/fopen.3.html

标签: c segmentation-fault fopen fclose


【解决方案1】:

为什么calloc(3,sizeof(struct student *)) 用于结构指针而不是结构成员?对于 3 个结构成员,它似乎必须是 calloc(3,sizeof(struct student))

【讨论】:

    【解决方案2】:

    不知道学生结构指针和内容是否正确。尝试在 fopen 之后立即关闭文件。如果没有分段错误,那么您的问题在于指针或内存分配。

    【讨论】:

    • 所以在调用 writeData() 之前查看学生初始化和使用的代码...
    • @amitakCs - 好吧,如果你已经做了一些调试,为什么不告诉我们呢?
    • 嗯,数据输入正确。我可以打印数据。我可以进行插入、删除。处理数据时我没有问题。我发现的唯一问题是:当我只使用 fopen 时,我找不到我的数据。但是当我注释掉 fopen 时,我再也没有问题了。所以现在我没有任何想法。如果问题依旧,我会使用gdb调试代码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 2012-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-28
    相关资源
    最近更新 更多