简体   繁体   中英

Segmentation fault when calling fread() c++

I dont understand the mistake I am making. I tryed alot but I am unable to read my FILE. Basically I write an structure into a file named 0.txt / 1.txt / 2.txt ... based of account amound. I realy seached hours to fix my problem but I dont understand how I can fix and why I get the ERROR. Also I have no problem in complining my code (with dev c++) but when I press on Load Accounts Button I get the ERROR " Segmentation Faul t" (using windows 7). I noticed that the problem is at fread() line in function ladeAccounts(). The name of my Structure is "iAccount". The variable infoma is as iAccount typed and the "number of accounts existing" typed as int anzahl in newAccount() decides the path.

iAccount looks like this:

 struct iAccount
    {
        string ID;
        string password;
        int level;
    };

This is how I write my STRUCT into the FILE:

void Account::newAccount(int anzahl, string username, string pw, int lvl)
    {
        iAccount neu;
        neu.ID = username;
        neu.password = pw;
        neu.level = lvl; 
        ss.str("");
        ss<<anzahl;
        s = ss.str();
        s = "Accounts/"+s+".txt";        
        f1 = fopen(s.c_str(), "w");
        fseek(f1, 0, SEEK_SET);
        fwrite(&infoma, sizeof(iAccount), 1, f1);        
        fclose(f1);             

    }

This is how I read the File (ERROR APPEARS when I call fread()

void Account::ladeAccount(int nummer)
    {
        stringstream sa;
        iAccount account_geladen;
        sa.str("");
        sa<<nummer;        
        s = sa.str();  
        s = "Accounts/"+s+".txt";     
        f2 = fopen(s.c_str(), "r"); 
        fseek(f2, 0, SEEK_SET);                  
        fread(&infoma, sizeof(infoma), 1, f2);               
        fclose(f2);                          

    }

Thank you for your help. I have no clue where my problem is and as I said I am searching for hours.

EDIT: The file gets opened I tryed it (f2 is true!).

EDIT": ERRNO = 0 !!!

SEE HERE:

ostringstream Str;
Str << errno;   
infoma.ID = Str.str(); 

Just did this to see the result of errno in my wxtextlabel.

Reason

You are most probably calling fread on a NULL file handle. So you have two problems here:

  1. In your code (you don't check if fread succeeds or returns a NULL value)
  2. Your file can't be opened for some reason (this, you should investigate...)

Explication

fopen (see documentation ) can return a NULL handle for different reasons. If you don't check the validity of the handle before calling fread you will have a segmentation fault.

Tips

As you can read in the official documentation I linked above, on most library implementations the errno variable can help you giving the system-specific error code on failure. This could help you debugging your error in opening the file.

Side Issues

Once you solve this bug in our code you will have other issues . As people (notably @Christophe) remarked in other answers, there is a structural problem in your code because you try to serialize/deserialize on your file objects non POD (aka your strings). Since string are complex objects you can't serialize them directly.

The approach of using an array of characters will work correctly, as simple types can be handled the way you coded.

For this reason, you can use the std::string c_str() method to obtain a null terminated array of chars from your string and store it in the file.

The opposite operation is even more straightforward, as you can initialize a std::string simply passing the deserialized array of chars:

std::string str(the_array);

You have a problem because you use fread() to load binary data. But this works only with plain old data (POD) objects.

It uses to give desastrous results with less trivial objects especially if the internals of these manage dynamic memory allocaton and/or pointers like it's the case here with strings.

By the way:

If you read/write binary data, you should really use "rb"/"wb" as mode for fopen() . If you don't you would'nt necessary have a seg.fault, but your data might be incorrect on some systems.

Edit:

Sorry, I didn't read well enough: if it happens right at fread() the reason provided by Alex will certainly help. However I leave this answer because as soon as you've solved your fopen() issue, you might get segmentation errors if you try to work with the object that you've read. If you're not conviced, look at sizeof(iAccount) and compare it to the size your string content.

EDIT if(f2) is true so I am wrong and file got opened successfull right?

I found out that the file is not opened/the fopen can not handle with the path for example 0.txt . Also I tryed to enter the path directly without building it (without stringstream and so on). Still I have the problem of the segmentation fault. I checked everything the file exists in the folder Accounts. I have an other file called "Accounts.txt" in the same folder and there I have no problem reading the amound of accounts existing (also using a struct). There I dont even check if the fopen had success but it works anyway I will write the code for the file-open-check later.

The code for the reading/writing into Accounts/Accounts.txt is:

struct init{
    int anzahl_1;};
    init anzahl;
    FILE* f;
    static string ss = "Accounts/Accounts.txt";      
int account_anzahl1()
{ 

    f = fopen(ss.c_str(), "r");       
    fread(&anzahl, sizeof(init), 1, f); 
    fseek(f, 0, SEEK_END);      
    fclose(f);
    return anzahl.anzahl_1;


}
void account_anzahl_plus()
{
    anzahl.anzahl_1 = anzahl.anzahl_1 +1;     
    f = fopen(ss.c_str(), "w");
    fwrite(&anzahl, sizeof(init), 1, f);        
    fclose(f);    
}

There I have no problem!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM