Jump to content
  • Advertisement
suliman

Different data size in release/debug? (c++)

Recommended Posts

Hi!

I save/load my game data as binary files using fwrite() and fread(). I save large blocks of data by using: "fwrite(&item->startSave,1,&item->endSave-&item->startSave,f);" on my classes. This might be primitive but it has worked very well for me for many years.

However:
I now realise (with a new version of the IDE and some other upgrades) there seem to be something not working well when loading data (the binary file) in release mode (the data was saved in debug mode and loads well from there). At first it loads fine some classes but some data later on in the load function seems to be corrupt.

Is the size of the variables (arrays of ints and so on) changing between debug and release and can this be the problem? Some memory padding or something? Im using visual studio 2017 (c++) if that matters.

Thank you!

Edited by suliman

Share this post


Link to post
Share on other sites
Advertisement

Remember the sizeof() a struct/class includes some things you're not supposed to reason about as a user of the language, such as the VTable if the type (or any of its supertypes) have any virtual methods.

You may need to re-do your serialization from scratch. If you are going to use C-isms like fwrite() and fread(), which means casting to/from void pointers, you must restrict yourself to serializing only structs/classes which contain no pointers, and have no virtual methods.

Share this post


Link to post
Share on other sites

I only save sections of data that includes no pointers. See example below (only saves stuff between saveStart and saveEnd). So given that, it still means it can only work in debug mode? So the size of these ints and floats are different in debug and release mode?

class myClass{
public:

bool saveStart;

int something[10];
float mass;
float height;
char name[200];

bool saveEnd;

int notSavedData;

void doStuff();
int getMass();

};

 

Share this post


Link to post
Share on other sites
4 hours ago, suliman said:

 

Is the size of the variables (arrays of ints and so on) changing between debug and release and can this be the problem? Some memory padding or something? Im using visual studio 2017 (c++) if that matters.

An array if integers in debug is the same size as it is in release.  The differences between debug and release will depend on optimization settings for things like alignment, which will affect the in-memory size of user defined structs and arrays of those structs.

Can you include your entire load/save code?

Share this post


Link to post
Share on other sites

If you're curious, there may be ways of examining the layout. Maybe there's something available in your development environment. Or, you could examine the output files in a hex editor, or compute and log the differences between the addresses of each member of interest and 'saveStart' (as e.g. char *'s). By comparing results in debug and release, you might be able to identify where and why things are going wrong.

It seems like it could be interesting and perhaps informative to figure that out, but as has been mentioned, this approach has various caveats associated with it, so it might be worth at least considering alternative approaches.

Share this post


Link to post
Share on other sites
Quote

(only saves stuff between saveStart and saveEnd)

Well, do some analysis yourself. Make a test program which emits the sizeof(), the address, the relative address of ::saveStart and the relative address of ::saveEnd... and compare the output in debug and release builds. And if they come out identical... be sure to post your test-program's code when you post your results here.

Share this post


Link to post
Share on other sites

IMO if you're having this kind of problem your serialization is broken. You should never assume a given class object layout in memory. You don't control it, the compiler does. Write each data member on it's own.

Share this post


Link to post
Share on other sites

I found I had included something that wasnt strictly primitive data in my saved data-range...

This seem to work fine in debug mode but not in release (maybe debug allows some errors, or "fixes" the errors trying to be helpful but instead masking a problem i actually had all along).

Those save/load ranges that did only (truely) include primitive data worked well even in release build.

Edited by suliman

Share this post


Link to post
Share on other sites
13 hours ago, suliman said:

I found I had included something that wasnt strictly primitive data in my saved data-range...

This seem to work fine in debug mode but not in release (maybe debug allows some errors, or "fixes" the errors trying to be helpful but instead masking a problem i actually had all along).

Those save/load ranges that did only (truely) include primitive data worked well even in release build.

What did you include?  Also, if what you were actually saving was different from what you posted above, why did you post it?

Share this post


Link to post
Share on other sites

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

  • 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!