weird iostream/fstream behavior

J

Jim Strathmeyer

So I'm having some weird problems with file output. If I try to boil
this problem down to a small, simple program to just show what problems
I'm having, I can't get the same problematic behavior. I have a
function:

bool Tourist::CreateMaps() {
debug.Out() << "Tourist::CreateMaps" << std::endl;
std::eek:fstream out((player_name + ".sav").c_str(),std::ios::eek:ut);

std::string ms = Random::MapStart();
std::string ma = Random::RandomMapArena();
std::string mr = Random::RandomMapRooms(3);
std::string me = Random::MapEnd();

debug.Out() << "mr is " << mr << std::endl;

out << "4\n";
out << ms << std::flush;
out << ma << std::flush;
out << mr << std::flush;
out << me << std::flush;

out.close();

return true;
}

debug.Out returns an ostream & that outputs to a debuggin file. In the
debugging file I see the output of "mr is" and it looks correct.
Specifically, there is a line "3 43 1 33 1 1 0". (For this example,
player_name = "jim".) However, in jim.sav the line "3 33 -1075888520 33
-1075888520 1 0" is written. If I change the std::flush's to
std::endl's, the correct line shows up in jim.sav (but the extra endl's
break the file and it can't be read in correctly.)

Any idea what the heck is going on here? I can't figure out how or why
the line is getting mangled. Any more information I need to provide? The
member function Random::RandomMapRooms returns a string that is build
using a string stream and converted using the str() member.
 
J

Jonathan Mcdougall

Jim said:
So I'm having some weird problems with file output. If I try to boil
this problem down to a small, simple program to just show what problems
I'm having, I can't get the same problematic behavior. I have a
function:

bool Tourist::CreateMaps() {
debug.Out() << "Tourist::CreateMaps" << std::endl;
std::eek:fstream out((player_name + ".sav").c_str(),std::ios::eek:ut);

std::string ms = Random::MapStart();
std::string ma = Random::RandomMapArena();
std::string mr = Random::RandomMapRooms(3);
std::string me = Random::MapEnd();

debug.Out() << "mr is " << mr << std::endl;

out << "4\n";
out << ms << std::flush;
out << ma << std::flush;
out << mr << std::flush;
out << me << std::flush;

You don't need to do that. close() flushes the buffer automatically.
out.close();

return true;
}

debug.Out returns an ostream & that outputs to a debuggin file. In the
debugging file I see the output of "mr is" and it looks correct.
Specifically, there is a line "3 43 1 33 1 1 0". (For this example,
player_name = "jim".) However, in jim.sav the line "3 33 -1075888520 33
-1075888520 1 0" is written.

What are these values? Where do they come from? The large negative
numbers usually mean you are accessing invalid memory, such as already
deleted objects.
If I change the std::flush's to
std::endl's, the correct line shows up in jim.sav (but the extra endl's
break the file and it can't be read in correctly.)

Any idea what the heck is going on here? I can't figure out how or why
the line is getting mangled. Any more information I need to provide? The
member function Random::RandomMapRooms returns a string that is build
using a string stream and converted using the str() member.

Are you returning an object or a pointer to a buffer? For example, are
you returning

oss.str().c_str()

? If so, the stream is already destroyed and the buffer does not exist
anymore. It looks like the problem is before the output, not the output
itself. Try to output the same value in two different streams at the
same place:

jim_sav << the_string;
jim_sav.close();

std::cout << the_string << std::flush;

If the first one is broken but the second one works, the file stream is
probably corrupted.


Jonathan
 
J

Jim Strathmeyer

What are these values? Where do they come from? The large negative
numbers usually mean you are accessing invalid memory, such as already
deleted objects.

Yeah, guess I didn't really explain it. The exact line should be "3 43 1
33 1 1 0". This is the line of text in the string (the lines being
separated by \n's.)
Are you returning an object or a pointer to a buffer? For example, are
you returning
oss.str().c_str()

I'm returning oss.str(), which I think returns a string object which
gets correctly copied when it is returned. (I understand why the buffer
would no longer exist and should not be returned.)
 
J

Jim Langston

Jim Strathmeyer said:
So I'm having some weird problems with file output. If I try to boil
this problem down to a small, simple program to just show what problems
I'm having, I can't get the same problematic behavior. I have a
function:

bool Tourist::CreateMaps() {
debug.Out() << "Tourist::CreateMaps" << std::endl;
std::eek:fstream out((player_name + ".sav").c_str(),std::ios::eek:ut);

std::string ms = Random::MapStart();
std::string ma = Random::RandomMapArena();
std::string mr = Random::RandomMapRooms(3);
std::string me = Random::MapEnd();

debug.Out() << "mr is " << mr << std::endl;

out << "4\n";
out << ms << std::flush;
out << ma << std::flush;
out << mr << std::flush;
out << me << std::flush;

out.close();

return true;
}

debug.Out returns an ostream & that outputs to a debuggin file. In the
debugging file I see the output of "mr is" and it looks correct.
Specifically, there is a line "3 43 1 33 1 1 0". (For this example,
player_name = "jim".) However, in jim.sav the line "3 33 -1075888520 33
-1075888520 1 0" is written. If I change the std::flush's to
std::endl's, the correct line shows up in jim.sav (but the extra endl's
break the file and it can't be read in correctly.)

Any idea what the heck is going on here? I can't figure out how or why
the line is getting mangled. Any more information I need to provide? The
member function Random::RandomMapRooms returns a string that is build
using a string stream and converted using the str() member.

What happens when you don't do the flush? How happens if you make it:

out << "4\n" << ms << ma << mr << me << std::endl;
out.close();
 
J

Jim Strathmeyer

Jim Langston said:
What happens when you don't do the flush? How happens if you make it:
out << "4\n" << ms << ma << mr << me << std::endl;
out.close();

The same thing that happens with the flushes; just showing that the
flushes don't solve anything, but replacing them with std::endl's does,
which is weird, because all the endl does is output a '\n' and do a
flush.
 
J

Jonathan Mcdougall

Jim said:
Yeah, guess I didn't really explain it. The exact line should be "3 43 1
33 1 1 0". This is the line of text in the string (the lines being
separated by \n's.)



I'm returning oss.str(), which I think returns a string object which
gets correctly copied when it is returned. (I understand why the buffer
would no longer exist and should not be returned.)

The problem is not with the string nor with the output. It is with the
values which are being concatenated in the string. It looks like third
and fifth objects generating the values are invalid while the others
are (seemingly) ok, though you never know. This looks a lot like
undefined behavior.

Would it be possible to show a bit more code? Showing how the values
are obtained would help.


Jonathan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Weird Behavior with Rays in C and OpenGL 4
eof error using '>>' in fstream 2
Crossword 14
fstream File i/o 1
TF-IDF 1
fstream - write a file 3
Erratic Container Behavior (list & vector) 2
fstream Buffers 26

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top