   std::string's implementation
  Hi all.I've noticed that a lot of people here are very big advocates of using std::string instead of char[]'s.  I've considered using them as it makes my string manipulation tons easier, but as a general rule I don't because I am unaware of the memory overhead and what it does behind the scene.From looking at the std::string in the debugger, it seems like it employs a dynamic buffer to store the string.  Additionally, the actual character buffer is stored as a pointer to said buffer.This makes writing and reading binary data a big pain as I am afraid that writing a std::string to file and reading back in will yield invalid pointers, memory, and so on.  I prefer using char arrays for this particular reason.  I exactly know the size of the buffer, I know how it's going to be written out, I know how it's going to be read back in.So could someone fill me on the actual implementation of std::string and what does in the background?  I'd much rather know that my strings are 32 bytes in an array, unchanging, than an object that may/may not allocate memory and that I have to write serialization code when reading and writing from and to disk.Many thanks :)Graf   
  Do the same thing you would do with char[], write str.size() followed by str.data(). Read them back by reading the size first, creating a std::string of that size and reading the data back into the buffer of the std::string.   ;  Writing C++ classes (that aren't POD) directly to disk is a bad idea. Get out of that habit immediately.You can use the length(), data(), and c_str() members of std::string to get everything you need to write the string to disk. (Hint: you can copy the string to a char array, then write that to disk if that's what you're comfortable with).   ;  What std::string does behind the scenes is implementation-dependent. Just because the implementation that comes with your compiler works one way, doesn't mean they all do.If you're thinking of using a std::string for binary dumps, then your complaint is quite silly -- strings are meant for strings of character data, not for dumps. If you want a dump in char form, I'd suggest a std::vector of char, rather than using a string.;Trap:Not really.  If I have a class with a "char s[64]", with no virtual functions, I can simply dump that entire class to file, and read it back in.  Very quick, very simple.  If I have a std::string within the class, I have to write a special serialization function for it, to specifically stream the data out.  That is something I'd like to avoid doing.jdhardy:Writing non-POD classes to disk (without virtual functions) is a common practice, especially if you need to load up tons of data really quickly without any additional pointer fixups or anything.  At my current job we do that to load up our meshes, textures, level data, scripts, and so on.  As soon as the file is read from disk into some buffer, we set a pointer and it's ready to go, no further post-processing on loaded data.My goal is two-fold : To be able to write out data -without- serialization, and to be able to predict how much memory I will need ahead of time.  std::string does neither, as "ABC" will take up less memory as a string than "ABCDEFGHI".  (char str[64]) will always take up 64 bytes, and I can budget around that, even make restrictions.  This is *extremely* important in situations with very tight memory (like the PS2).coldacid:I am talking about strings for character data (like names, paths and so on).  But I also need to be able to write the data out to file (like texture locations, skeletion names, etc) and read it back in a predictable manner.Regarding the different implementations.. then I'd like to know the implementation/overhead of .NET 2003's std::string.   ;  they made the << and >> operators and streams for a reason...   ;Quote:Original post by Code-Rthey made the << and >> operators and streams for a reason...Indeed they did.  But in my case I need data that's ready to go the second it's read in from file.  And it needs to be read into a giant chunk of memory.It's easy to make serialization functions (using streams and whatnot), but for classes that contain classes that contain classes I'll end up spending more time streaming in data (and converting data) than if I were able to simply read in a giant chunk, set a single pointer and be off with it.Additionally, <<'s and >>'s still does not resolve the fact that I cannot adequately budget memory.  If I have a thousand objects where each of them contains a string, what's the total amount of memory they all take up?  I won't know until I iterate through every single one and add the sums of the string lengths.  Whereas if each object had a char array of 32, you'd know exactly the amount of memory all the objects take up, regardless of data content.I guess in the end I'll use a mix of the two, which is more or less what I'm doing already.  For on-the-fly string manipulation (substrings, concats, etc) std::string will do me fine.  But as storage in classes/objects that persist and take up memory, char arrays will do.   ;  Surprisingly enough, std::string is a STRING class. It's designed for text. char[] is just a buffer, you can put anything you like in it. Yes, it's more flexible, but also inherently harder to use. If you are dealing with text, use std::string. Using streaming io vs lumped io (I have no idea what the correct term is there) is a matter of design with a bit of personal preference I think. Loading binary data from files I think the general consensus is to load the whole thing at once and cast as a struct*, much faster that streaming bit by bit. There probably is a way of streaming a whole struct at a time though. I use memory mapped files myself.   ;Quote:Original post by GrafalgarWriting non-POD classes to disk (without virtual functions) is a common practice, especially if you need to load up tons of data really quickly without any additional pointer fixups or anything.  At my current job we do that to load up our meshes, textures, level data, scripts, and so on.  As soon as the file is read from disk into some buffer, we set a pointer and it's ready to go, no further post-processing on loaded data.Er, there's more than just the virtual function pointers to worry about. Any member variables that are themselves classes of some sort, may contain virtual functions, or pointers or things that do not stay intact when directly dumped to file, and then back into RAM.The internal structures of those classes should be able to be changed independantly of their own interfaces. But that isn't possible if you need them to be binary compatible because they're dumped to file.But obviously the things you are using are in fact POD types, from what you describe, or it would not be working now.Are you more worried about the effort required to write [de]serialisation routines, or are you worried about performance of [de]serialisation routines?   ;Quote:Original post by GrafalgarTrap:Not really.  If I have a class with a "char s[64]", with no virtual functions, I can simply dump that entire class to file, and read it back in.  Very quick, very simple.  If I have a std::string within the class, I have to write a special serialization function for it, to specifically stream the data out.  That is something I'd like to avoid doing.If you have a class with a char[64] member, then that member is fundementally different from a class with an std::string member or a class with a char* member.  In particular, the former has a set size, while the latter two do not.  Trap was obviously refering to the case where your char array *doesn't* have a known size ahead of time, in which case you can't just dump your class to a file.  *edit: By the way, considering the speed of file i/o, chances are you're being paranoid for no reason.  The time neccessary to convert the data will be completely dwarfed by the time neccessary to actually read it.  So who cares?CM   