Jump to content
  • Advertisement
Sign in to follow this  
AfroFire

C/C++ Reading Binary Data Issue...

This topic is 3994 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys, I am trying to create my own archiving format (just for fun) and, everything has been going surprisingly smooth so far, but alas I ran in to a little snag. The code below is the load() function of my Archive class. You'll see in the source below (it's not too far down) where the code is crashing, on a char *buffer2 = new char(length); The program runs fine if I go ahead and change it to something like char buffer2[32]; or something, and read in the length, but then it'll crash on the next 'new' (e.g. in this case, that'd be newBuffer in this case, ignore the variable names, I've raped them in this experimentative process) Right after the source code you'll find the output from the program as supportive evidence of my claim (i.e. the new line is causing the crash). Debug shows only assembly output.
bool Archive::load(const std::string &file_name)
{
	file_stream.open(file_name.c_str(), fstream::in | fstream::binary);
	if(!file_stream.is_open())
	{
		/* File_Stream isn't open! */
		cout << "Stream Not Open!" << endl;	
		return false;
	}

	unsigned int test;

	file_stream.read((char*)header_data, sizeof(ArchiveHeaderData)); 
	cout << "Num. Of Elements In Archive: " << header_data->number_of_elements << endl;

	ArchiveData *temp = new ArchiveData();

	int length;

	file_stream.read((char*)&length, sizeof(int));
	cout << length << endl;

	char *buffer = new char(length);
	file_stream.read(buffer, length);
	cout << "File Name: " << buffer << endl;

	file_stream.read((char*)&length, sizeof(int));
	cout << length << endl;
 
        /***** CRASHES ON NEXT LINE     *****/
	char *buffer2 = new char(length);
        /***** CRASHES ON PREVIOUS LINE *****/
	file_stream.read(buffer2, length); // commenting out this line doesn't stop the crash, this suggests that it isn't this line causing the crash.
	cout << "Data Type: " << buffer2 << endl; // we never get here *sniff*

	file_stream.read((char*)&length, sizeof(int));
	cout << "Data Size: " << length << endl;

	char *newBuffer = new char(length);
	file_stream.read(newBuffer, 673342);
	cout << newBuffer << endl;

	file_stream.close();
	return true;
}

/**** OUTPUT ****/
Num. Of Elements In Archive: 4
17
File Name: protossbase-1.jpg&#9786;N
3


Thank you for any help! Let me know if you need any more source code (though I don't understand why), also feel free to suggest any alternative ideas you may have for loading data - I'm in the process of learning! Currently what I do is I've created a small C# application I have named "Archer" which provides an interface for packaging up the files in to the archive. In the future I plan to research some sort of compression techniques/algorithms in order to make the archiver useful in some sort of way. Since this will be primarily used for games and the such, adding directories is an iffy thing (though I do have some "ghost code" lying around in the code that do support directories). Okay, enough rambling! Thank you again!

Share this post


Link to post
Share on other sites
Advertisement
Your fstream instance should be local to the function. Consider using std::vector instead of trying to manually handle dynamic arrays. ArchiveData, depending on what you want to do with it, could be declared auto rather than using a pointer.

This will make your code easier.

Share this post


Link to post
Share on other sites
Well, right away SiCrane was right - I just changed all the () to brackets.

However, for a brief second I thought he was wrong because I just changed the second two "new"s to [] and left the first one (), and it still crashed.

But with all three as [] it works.

WHY ?

Also, what is the difference between () and [] in this case?

rip-off - good idea, I'll try implementing that as well.

Share this post


Link to post
Share on other sites
new char(32) allocates a single char with the value 32. new char[32] creates an array of 32 chars.

Share this post


Link to post
Share on other sites
Both "ways" aren't synonymous. () is for construction syntax.

new char(x) creates a single char on the heap whose value is x (assuming that value fits in to a char).

new char[x] creates an array of x chars on the heap. So the following code that you use has all kinds of nasty issues:


char *buffer = new char(length);
file_stream.read(buffer, length);



The problems this causes might not manifest immediately as your program exhibits what the C++ standard calls "undefined behaviour".

If you take rip-off's advice, you'll avoid this kind of trouble and ambiguity out-right.Learning to use std::vector<> is one of the best things that can happen to anyone starting out with C++.

Share this post


Link to post
Share on other sites
That makes sense - I briefly considered the idea that what I was doing was constructing a char with a value but I, for some reason, abandoned the idea and thought there was something going on underneath the covers (c++ magic) - I seem to have picked this idea up from long ago and never considered a char a "normal" object.

I'm way off - it has been awhile since I touched up on stuff like this (I'm not new to c++, Ive just been spoiled by std::string)

Share this post


Link to post
Share on other sites
Just an update - how the heck would one use std::vector to read in from a stream.

Currently I'm using fstream to open my file, and doing something like:

vector_variable.push_back(file.get()) doesn't work since it just seems to returns a single character (casted to int) and thus I'd have to loop through in order to load everything - this sounds like more of a hassle then just doing what I'm doing now.

Also using file.get(char*, int size) seemed rather pointless since that's the structure I'm trying to get away from, and that returns a *this pointer - pointless.



Is there something else you guys had in mind?


Share this post


Link to post
Share on other sites
Quote:
Original post by AfroFire
Just an update - how the heck would one use std::vector to read in from a stream.



char *buffer = new char[length];
file_stream.read(buffer, length);




becomes


std::vector<char> buffer(length);

assert(!buffer.empty());
file_stream.read(&buffer.front(), length);




That's 3 memory leaks eliminated from your original code.

Share this post


Link to post
Share on other sites
Ah, interesting - I always assumed .front() returned a iterator, I'll try this when I get home - thanks so much for your help the_edd.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!