Sign in to follow this  

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

This topic is 3777 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
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
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
Quote:
Original post by AfroFire
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.


begin() and end() are iterators, front() and back() are Type references (where Type is the vectors template argument).

Share this post


Link to post
Share on other sites
Ahh, I'm all messed up.

In a C# Linked list - First() and Last() are Nodes, sort of like the front and back I suppose :)


So we've got begin, end, first, last, and front, back.

Thanks a lot everyone for the clarifications.

Share this post


Link to post
Share on other sites
Just got home, played a few games of StarCraft and then got back to work:

However, I must be doing something else wrong on this whole reading in to a std::vector thing -

Now it's just back to crashing again:


std::vector<char> buffer;

file_stream.read((char*)&length, sizeof(int));
file_stream.read(&buffer.front(), length);



So, now it just crashes right away on the very first read.

Even if I initialize it with a reserve it doesn't do anything, so I'm just completely confused as to how this should work. Thank you for any more time you can give me.

Share this post


Link to post
Share on other sites
Quote:
Original post by AfroFire
Just got home, played a few games of StarCraft and then got back to work:

However, I must be doing something else wrong on this whole reading in to a std::vector thing -

Now it's just back to crashing again:

*** Source Snippet Removed ***

So, now it just crashes right away on the very first read.

Even if I initialize it with a reserve it doesn't do anything, so I'm just completely confused as to how this should work. Thank you for any more time you can give me.


.reserve() is not .resize() (even for chars). [smile]

Share this post


Link to post
Share on other sites
Quote:
Original post by AfroFire
Now it's just back to crashing again:

*** Source Snippet Removed ***

So, now it just crashes right away on the very first read.

Even if I initialize it with a reserve it doesn't do anything, so I'm just completely confused as to how this should work. Thank you for any more time you can give me.


Re-read the example code I gave a few posts back. Note how I initialised the vector to a given size by passing an argument to the constructor.

Take 20 minutes to properly read up on std::vector. It'll be the most important 20 minutes of your C++ programming career. All this guessing isn't doing you any favours.

Edd

Share this post


Link to post
Share on other sites

This topic is 3777 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this