[C++] Reading and Writing an STL vector with fstream

Started by
10 comments, last by Zahlman 14 years, 9 months ago
I have a game that reads in a tile map through the fstream class. Recently, I learned about binary files, and I tried to convert my tilemap format. After a few changes, I slightly succeeded. I could save an SDL_Rect successfully, but there seemed to be problems with my vector for the tile map. It saved and read, seemingly correctly, but happened to fail afterwards. When I tried to access any instance from the vector, I was given a segmentation fault. After a TON of Googling, I found nothing. Just to see if it was a compatibility problem between fstream and vector or something, I loaded and saved the tile map as an array and then later converted to a vector for use. Turns out, the array makes it work perfectly. I have no idea why. Is there something I should know about concerning vectors and fstreams, and/or is there some special way to read and write vectors?
Advertisement
Can you post some code?
--------------------------------------Not All Martyrs See Divinity, But At Least You Tried
I'm still VERY new to C++ (I just finished the summer course last Thursday), so I'm not sure if the solution I'm about to propose is accurate or not =)
Regardless, here we go...

Are you trying to access the vector through a pointer?

When vectors are re-sized dynamically (using push_back() for instance), the "newly sized" vector is moved to a completely different location in memory. Assuming that your vector has not been declared with a "pre set" size (or assuming that you're exceeding this size), it will be dynamically re-sized when it is updated with data from your fstream.

So, if you're trying to access the vector through a pointer, the pointer is pointing to the ORIGINAL memory location of the vector, NOT the new location where the vector actually resides.

The reason an array works is because they are static in their size and memory locations. You cannot dynamically re-size an array, therefore, if will always remain at the same location in memory, and any pointer pointing at the array will work.
Quote:Original post by tycse
I'm still VERY new to C++ (I just finished the summer course last Thursday), so I'm not sure if the solution I'm about to propose is accurate or not =)
Regardless, here we go...

Are you trying to access the vector through a pointer?

When vectors are re-sized dynamically (using push_back() for instance), the "newly sized" vector is moved to a completely different location in memory. Assuming that your vector has not been declared with a "pre set" size (or assuming that you're exceeding this size), it will be dynamically re-sized when it is updated with data from your fstream.

So, if you're trying to access the vector through a pointer, the pointer is pointing to the ORIGINAL memory location of the vector, NOT the new location where the vector actually resides.

The reason an array works is because they are static in their size and memory locations. You cannot dynamically re-size an array, therefore, if will always remain at the same location in memory, and any pointer pointing at the array will work.


Whoa, sounds good! But, this also means bad stuff for me. Do you know how I can dynamically retrieve the new location of the vector without having to use a statically-sized variable? Turns out I'm having a few problems later on in my programming career, as I never got to learn much of the STL library.
I'm not sure if this'll help you, but you can use std::copy to copy to/from streams?

Some cursory googling gave: this.
Quote:
Whoa, sounds good! But, this also means bad stuff for me. Do you know how I can dynamically retrieve the new location of the vector without having to use a statically-sized variable? Turns out I'm having a few problems later on in my programming career, as I never got to learn much of the STL library.

"Dynamically retrieving the new location of the vector" is going about things in the wrong fashion, almost certainly. Show us the code you're using now that is breaking, and we'll tell you what's wrong with it.

Be careful with your terminology. What you usually want when serializing a vector is the data contained in the vector -- not the vector itself. Therefor, the "location of the vector" is not germane the to the discussion. You want the location of the data, which you can get at via &myVector[0]. But you cannot persist that resulting address for long, because changes to the vector may invalidate it. You can, however, use it to serialize the vector data (although you don't need to, you can also walk the vector and serialize each data element).

Serialization in C++ can be tricky, it's full of gotchas because of the various bits of undefined behavior in the language -- for example, writing structs or class directly is brittle and prone to breakage.

Show us what you're actually doing.
Here are the important bits of the code (This is from a different file, but it gives me the same error);

#include <fstream>#include <vector>#include <iostream>int main() {	std::vector<int> first(5);	std::vector<int> second(5);        //For this example, I have static vectors. In my real program my vector is resized by a value read in through an ifstream	for(unsigned int i = 0; i < second.size(); i++) {		second = i;	}		std::ifstream reader("foo.data", std::ios::binary);	reader.read((char *) &first, sizeof(first));	reader.close();	        std::cout << first[0] << std::endl; //This is what gives me a segmentation fault	std::ofstream writer("foo.data", std::ios::binary);	writer.write((char *) &second, sizeof(second));	writer.close();		return 0;}


According to you guys, I should be accessing the elements of the vector, and not the vector itself. Am I right in thinking this? Also, with this test application, I found out that I am getting a segmentation fault at the end (with the returning of main), even if I don't try to access any element of my "first" vector.
By the way, you guys, my vector only stopped working once I converted to binary files. Previously, I wrote each element of the vector into a text file. At that time, it worked. Should I also be writing in the elements of the vector into the binary file, and not the vector itself?
Read and write elements of the vector. Not the vector itself.
OK, yeah, writing each element works (like before), though it is a little bit less convenient. Oh well.

This topic is closed to new replies.

Advertisement