Archived

This topic is now archived and is closed to further replies.

Classes allocating memory, reading/writing to file

This topic is 5589 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

Hi, The problem: Say I have a class like so...
  

class Dummy
{
Dummy(int size);
~Dummy();
private:
int allocsize;
char* buffer;
};

Dummy::Dummy(int size)
{
 allocsize = size;
 buffer = new char[size];
}
Dummy::~Dummy()
{
 allocsize = 0;
 delete[] buffer;
}
  
As you can see, this class derives memory right after the call to the Constructor. The problem lies when writing/reading to file. Hence...
  
#include <fstream>

Dummy* dumdum = new Dummy(64);

int main()
{
  fstream iofile("Somefile", ios::out, ios::binary);
  iofile.write((char *)dumdum, sizeof(dumdum);
}
  
; Will not write the whole buffer (64 bytes) to file. Sizeof(dumdum) in this case turned out to be 8 bytes for me. Before and after allocation. When reading it in I have the same problem. For reading in a Dummy*, should I call the constructor first or after I read in? What would be the best solution to this reading/writing problem? I''ve done a search on the forums, and I found nothing. But it''s possible I have missed something. If you know of a related topic please tell me, and save your typing molecules. Thanks in advance, Destroyer

Share this post


Link to post
Share on other sites
sizeof(dumdum) should return something like 4? 8 seems like
you''re running on a 64-bit machine.

Anyway, since you keep allocsize around, why not use it?


iofile.write((char *)dumdum, allocsize);


That tells write you want allocsize number of bytes to be
written. Also, it''s probably a good idea to write out
the allocsize first , so you have an idea of how many
bytes to read back...



Kami no Itte ga ore ni zettai naru!

Share this post


Link to post
Share on other sites
Thanks,

But there''s a slight problem with that.

The size of the buffer can be figured out when reading it in.

Doing this:

  
iofile.write((char *)dumdum, allocsize);


Would read in 64 bytes. But 4 bytes would go to the integer, and only 60 bytes would go to the buffer. Correct ?

I can''t read it straight into the buffer since its private.
Also you might say that I should just read in an extra 4 bytes to compensate for the int.
Also I know that a char is 1 byte, and an int is 4. Since they''re in a class I think the extra 3 bytes is probably due to performance issues. Would I have to read in an extra 3 bytes on top of those 4 bytes from the int?

I have a much bigger class than this, and this is only used as an example.

Would I have to find out the sizeof my bigger class, count the bytes they take up (which is extremely difficult since its a derived class, and has classes as members), and then find out how many extra bytes are added for performance issues and compensate for that when I''m reading it in?

Am I making any sense ?

Thanks in advance,

Destroyer

Share this post


Link to post
Share on other sites
It is likely 8 bytes because the compiler is padding the class out to 4 byte or 8 byte boundaries. This is pretty common even on 32-bit machines.

I''d recommend against writing out classes/structs directly to a file - it can cause numerous problems - write out the elements of the class itself as the correct types.

Furthermore if you are trying to write a string as that second data member then it is all wrong as you are writing out the POINTER to that memory.

Look into object persistence/streaming

Share this post


Link to post
Share on other sites
Oops, I had a brain-lapse when I replied the first time.

Now I see that dumdum is an array of 64 Dummy *.

So really, what you''re trying to do is you''re writing out an
array of 64 pointers (though using the wrong size).

I don''t know how that would be useful when you read them
back, as the pointers are meaningless the next time you
run your program.

Do a search on "Write Object to Binary Files" and you should
find numerous posts related to this topic (which I''ve
answered a few...).



Kami no Itte ga ore ni zettai naru!

Share this post


Link to post
Share on other sites
Hi,

quote:
Original post by SteveC
I''d recommend against writing out classes/structs directly to a file - it can cause numerous problems - write out the elements of the class itself as the correct types.



I agree, but the problem occurs when the members are private that''s just about impossible .

quote:
Original post by tangentz
Oops, I had a brain-lapse when I replied the first time.

Now I see that dumdum is an array of 64 Dummy *.




No, the line
Dummy* dumdum = new Dummy(64);
creates a single dumdum instance that just so happens to be a pointer, and is allocated memory and calls the constructor. It''s not an array of pointers.

quote:
Original post by SteveC
Look into object persistence/streaming



I think I will...

Is there some other way around this that I haven''t seen or heard yet?

Thanks in advance,

Destroyer

Share this post


Link to post
Share on other sites
quote:
Original post by Destroyer
No, the line
Dummy* dumdum = new Dummy(64);
creates a single dumdum instance that just so happens to be a pointer, and is allocated memory and calls the constructor. It''s not an array of pointers.



Man... I swear the fonts on my system made the () look
like []...



Kami no Itte ga ore ni zettai naru!

Share this post


Link to post
Share on other sites
tangentz:
it _should_ be 8 bytes (1 int+1 ptr)

Destroyer:
you should write an accessor function for allocsize like


int Dummy::GetSize()
{
return allocsize;
}


to know the real size of the buffer (if you always store its size correctly). using sizeof will only tell you the size of the class and not the pointers associated with it (which would be the 8 bytes you mentioned).


btw about the problems with private members:
write a _memberfunction_ to print out the contents of the class or make additional accessor functions like the one above. these functions dont even break the purpose of the private keyword as the value cant be changed (read only)


mfg Phreak
--
"Input... need input!" - Johnny Five, Short Circuit.

Share this post


Link to post
Share on other sites
You could just provide a serialize-like function in your Dummy. eg:

  
class Dummy
{
// same as previous

public:
void Write(ostream &os);
};
void Dummy::Write(ostream &os)
{
os.write(&allocsize, sizeof allocsize);
for (int i = 0; i < allocsize; ++i)
os.write(buffer, allocsize);
}
Dummy* dumdum = new Dummy(64);
int main()
{
fstream iofile("Somefile", ios::out, ios::binary);
dumdum->Write(iofile);
// and remember to delete your dumdum

}

Share this post


Link to post
Share on other sites
quote:
Original post by LousyPhreak

btw about the problems with private members:
write a _memberfunction_ to print out the contents of the class or make additional accessor functions like the one above. these functions dont even break the purpose of the private keyword as the value cant be changed (read only)



Never really thought about that. That seems like a nice solution as well . Thank you .

quote:
Original post by DerekSaw



    
class Dummy{
// same as previous

public: void Write(ostream &os);
};

void Dummy::Write(ostream &os)
{ os.write(&allocsize, sizeof allocsize);
for (int i = 0; i < allocsize; ++i)
os.write(buffer, allocsize);
}

Dummy* dumdum = new Dummy(64);
int main()
{
fstream iofile("Somefile", ios::out, ios::binary);
dumdum->Write(iofile);
// and remember to delete your dumdum

}


I tested this out and it most definately seems to work. I wrote an reading equivilant and it works . Thank you very much. I never really thought about that as well .

Thanks to all! You've been a great help!

Destroyer




[edited by - Destroyer on August 27, 2002 11:06:49 AM]

Share this post


Link to post
Share on other sites