1

i have a binary file where i save my struct:

struct vec
{
    string author;
    string name;
    int pages;
    string thread;
    vec *next;
};

write to file function:

    void logic::WriteInfoToFile()
{
    if (first != NULL)
    {
        pFile = fopen(way.c_str(), "wb");
        if (pFile != NULL)
        {
            fseek(pFile, 0, SEEK_SET);
            temp = first;
            while (temp != NULL)
                {
                    WriteString(temp->author,pFile);
                    WriteString(temp->name,pFile);
                    fwrite(&temp->pages,sizeof(int), 1, pFile);
                    WriteString(temp->thread,pFile);
                    temp = temp->next;
                }       
        }   
        fclose(pFile);
    }
}

write srtig function:

void logic::WriteString(string s, FILE *pFile)
{
    if (pFile != NULL)
    {   
        char *str = new char[s.length() + 1];
        strcpy(str, s.c_str());
        int size = strlen(str);
        fwrite(&size, sizeof(int), 1, pFile);
        fwrite(str, size, 1, pFile);
        delete [] str;
    }
}

read file:

void logic::ReadInfoFromFile()
{
    pFile = fopen(way.c_str(), "rb");
    if (pFile != NULL)
    {       
        fseek(pFile, 0, SEEK_END);
        if (ftell(pFile) != 0)
        {   
            fseek(pFile, 0, SEEK_SET);
            int check;
            while (check != EOF)
            //while (!feof(pFile))
            {
                temp = new vec;
                temp->author = ReadString(pFile);
                temp->name = ReadString(pFile);
                fread(&temp->pages, sizeof(int), 1, pFile);
                temp->thread = ReadString(pFile);
                temp->next = NULL;
                if (first == NULL)
                {
                    first = temp;
                    first->next = NULL;
                }
                else
                {
                    temp->next = first;
                    first = temp;
                }
                recordsCounter++;

                check = fgetc(pFile);
                fseek(pFile, -1, SEEK_CUR);
            }
        }
    }
    fclose(pFile);
}

read string:

string logic::ReadString(FILE *pFile)
{
    string s;
    if (pFile != NULL)
    {
        int size = 0;
        fread(&size, sizeof(int), 1, pFile);
        char *str = new char[size];
        fread(str, size, 1, pFile);
        str[size] = '\0';
        s = str;
        //delete [] str;   //WHY?????????!!!!!
        return s; 
    }   
    else
        return s = "error";
}

trouble is in read string function, where i free memory. " delete [] str " i get crash of program on this line.

but if i dont exempt memorry works good.

Help me please!

mrglut
  • 27
  • 5
  • Why are you doing all of this dynamic allocation to write a std::string? Just use `c_str()` and `string::size()`. All the information about the string is in those two functions. – PaulMcKenzie Nov 14 '14 at 12:44
  • You have a few problems with your code, mostly because you mix C functions with C++ code. One (minor) problem is that [`std::strlen`](http://en.cppreference.com/w/cpp/string/byte/strlen) doesn't return an `int`, but `std::size_t`. – Some programmer dude Nov 14 '14 at 12:44
  • And many of your problems will kind of automatically go away if you learn to use the [C++ input/output library](http://en.cppreference.com/w/cpp/io), and use [`std::string`](http://en.cppreference.com/w/cpp/string/basic_string) instead of `char*`. – Some programmer dude Nov 14 '14 at 12:45
  • i do it because i dont know how to write the string into binary file, I long suffered with this and decided to use char* while reading/writing – mrglut Nov 14 '14 at 12:49
  • `fwrite(&s.length(), sizeof(int), 1, pFile); fwrite(s.c_str(), 1, s.length(), 1, pFile);` – AndersK Nov 14 '14 at 12:50
  • @mrglut - Why didn't you show your attempt that you tried instead of resorting to char* and `new[]`? You introduced so many issues with your code by using new[] here. One right away is that your code doesn't know what to do if an exception occurs if `new[]` throws. – PaulMcKenzie Nov 14 '14 at 12:52
  • @Claptrap - fwrite needs 4 argument, and tou write 5. Can you write fread for string too please. – mrglut Nov 14 '14 at 12:58
  • @mrglut ah yes my bad, remove the second '1' i.e. `fwrite(s.c_str(), 1, s.length(), pFile);` – AndersK Nov 14 '14 at 13:00
  • @PaulMcKenzie - sry, but i really tried, like Claptrap says, but there are too many bugs. and then i have the idea to do something like this. – mrglut Nov 14 '14 at 13:00
  • @Claptrap so the fread something like this: string s;int size; fread(&size, sizeof(int), 1, pFile); fread(&s, 1, size, pFile); and know i have crash while reading from file – mrglut Nov 14 '14 at 13:05
  • @mrglut `fread( &size, sizeof(int), 1, pFile ); char buffer[MAX_STRLEN]; int len = fread(buffer,1,size, pFile); buffer[len] = '\0'; string s(buffer);` – AndersK Nov 14 '14 at 13:20

1 Answers1

3

You're off by one allocating size chars but overwriting size+1 (with the terminal '\0'). The memory manager doesn't like that.

char *str = new char[size];
fread(str, size, 1, pFile);
str[size] = '\0'
Oncaphillis
  • 1,888
  • 13
  • 15