locked
How to solve this trouble ? Please help me ! RRS feed

  • Question

    1. Hi everyone ! I'm fresher in c and c++. I'm having a trouble when I add new data into vector / list . I have a method like :
    void List(vector<Student> &result)
    {
    	ifstream list(saveurl, ios::in | ios::binary);
    	if (list.is_open())
    	{
    		Student st;
    		while (!list.eof())
    		{
    			if (list.read((char*)&st, sizeof(Student)))
    			{
    				result.push_back(st);
    			}
    		}
    		list.close();
    	}
    }
    



    First-chance exception at 0x5E84DF58 (msvcp120d.dll) in Student.exe: 0xC0000005: Access violation reading location 0x010FAA4C.
    
    If there is a handler for this exception, the program may be safely continued.


    what can I do now ? any suggestions for me ?

    Tuesday, March 17, 2015 11:01 AM

Answers

  • On 17/03/2015 20:31, "Tran Hoang Duc" wrote:

    as shown below is how is the Student class defined .

    struct DateTime
    {
            int day,month,year;
    };
    class Student
    {
            private :
                    __int64 RollNo;
                    string StudentName, Course, FatherName,Address,Country;
                    DateTime DateofBirth;
    }

    is it right ?

    Perfect, as I suspected :)

    Your Student class definition is just fine.

    The problem is how you serialize that to/from files.

    Since you have non-POD types like std::string as Student data members, you can't just dump your Student internal bytes to disk and read them back to disk.

    This won't work, because for example std::string has pointers inside, and the values of those pointers (memory addresses) are meaningless when you write them to file and later load them from file, as just raw bytes, like in this code showed above in this thread:

        ...
        Student st;
        while(list.read((char*)&st, sizeof(Student)))
    

     You have to think how to write your Student class to files.
    You can use XML, JSON, or even simple comma separated values text files.

    Even if you use some custom binary format for your Student instances, you should pay attention to properly write the text stored in your strings to files, and read that back into std::string data members.
     Giovanni

    • Marked as answer by Shu 2017 Tuesday, March 24, 2015 1:37 AM
    Tuesday, March 17, 2015 7:43 PM
  • as shown below  is how is the Student class defined .

    struct DateTime
    {
        int day,month,year;
    }
    class Student
    {
    private :
        __int64 RollNo;
        string StudentName, Course, FatherName, Address, Country;
        DateTime DateofBirth;
    };
    

    is it right ?

    Ah yes, Giovanni has spotted the problem. I think your code would work if you defined Student as

    class Student
    {
    private :
        __int64 RollNo; 
        char StudentName[64];
        char Course[64];
        char FatherName[64];
        char Address[64];
        char Country[64];
        DateTime DateofBirth;
    };
    

    But Giovanni is right, reading binary data into a class or struct is not the best idea.


    David Wilkinson | Visual C++ MVP

    • Marked as answer by Shu 2017 Tuesday, March 24, 2015 1:37 AM
    Tuesday, March 17, 2015 8:13 PM

All replies

  • The correct way to read a file into a vector is

    void List(vector<Student> &result)
    {
        ifstream list(saveurl, ios::in | ios::binary);
        if (list.is_open())
        {
            Student st;
            while(list.read((char*)&st, sizeof(Student)))
            {
                    result.push_back(st);
            }
        }
    }
    

    David Wilkinson | Visual C++ MVP

    Tuesday, March 17, 2015 11:25 AM
  • thanks for your opinion ! but same problem!

    I wrote it in visual studio 2013 !

    Tuesday, March 17, 2015 12:59 PM
  • thanks for your opinion ! but same problem!

    I wrote it in visual studio 2013 !

    Then I do not think the exception is actually coming from the code you have shown.

    To find out where the exception is coming from, the Debug menu you should find an item that allows you to break on C+ exceptions. Then you can look at the call stack and see what actually caused the exception.


    David Wilkinson | Visual C++ MVP

    Tuesday, March 17, 2015 2:16 PM
  • On 17/03/2015 12:25, "davewilk [MVP]" wrote:

    The correct way to read a file into a vector is

    [code]
    void List(vector<Student> &result)
    {
         ifstream list(saveurl, ios::in | ios::binary);
         if (list.is_open())
         {
             Student st;
             while(list.read((char*)&st, sizeof(Student)))
             {

    I'm not convinced this is a good way of reading a Student data from file.

    What is the layout of the Student class?
    How is the Student class defined?

    Reading some binary data from a file and stomping the bytes of a Student instance doesn't seem very good to me in general...

    Giovanni

    Tuesday, March 17, 2015 5:13 PM
  • as shown below  is how is the Student class defined .

    struct DateTime
    {
    	int day,month,year;
    };
    class Student
    {
    	private :
    		__int64 RollNo;
    		string StudentName, Course, FatherName,Address,Country;
    		DateTime DateofBirth;
    }
    is it right ?

    Tuesday, March 17, 2015 7:31 PM
  • On 17/03/2015 20:31, "Tran Hoang Duc" wrote:

    as shown below is how is the Student class defined .

    struct DateTime
    {
            int day,month,year;
    };
    class Student
    {
            private :
                    __int64 RollNo;
                    string StudentName, Course, FatherName,Address,Country;
                    DateTime DateofBirth;
    }

    is it right ?

    Perfect, as I suspected :)

    Your Student class definition is just fine.

    The problem is how you serialize that to/from files.

    Since you have non-POD types like std::string as Student data members, you can't just dump your Student internal bytes to disk and read them back to disk.

    This won't work, because for example std::string has pointers inside, and the values of those pointers (memory addresses) are meaningless when you write them to file and later load them from file, as just raw bytes, like in this code showed above in this thread:

        ...
        Student st;
        while(list.read((char*)&st, sizeof(Student)))
    

     You have to think how to write your Student class to files.
    You can use XML, JSON, or even simple comma separated values text files.

    Even if you use some custom binary format for your Student instances, you should pay attention to properly write the text stored in your strings to files, and read that back into std::string data members.
     Giovanni

    • Marked as answer by Shu 2017 Tuesday, March 24, 2015 1:37 AM
    Tuesday, March 17, 2015 7:43 PM
  • thanks alot bro!
    Tuesday, March 17, 2015 7:50 PM
  • as shown below  is how is the Student class defined .

    struct DateTime
    {
        int day,month,year;
    }
    class Student
    {
    private :
        __int64 RollNo;
        string StudentName, Course, FatherName, Address, Country;
        DateTime DateofBirth;
    };
    

    is it right ?

    Ah yes, Giovanni has spotted the problem. I think your code would work if you defined Student as

    class Student
    {
    private :
        __int64 RollNo; 
        char StudentName[64];
        char Course[64];
        char FatherName[64];
        char Address[64];
        char Country[64];
        DateTime DateofBirth;
    };
    

    But Giovanni is right, reading binary data into a class or struct is not the best idea.


    David Wilkinson | Visual C++ MVP

    • Marked as answer by Shu 2017 Tuesday, March 24, 2015 1:37 AM
    Tuesday, March 17, 2015 8:13 PM