0

I'm running tests to see how variables are getting placed on the memory and sizing them out when I use a struct. Consider I have a struct that looks like below:

typedef struct _ttmp
{
    WCHAR wcsTest1[13];
    WCHAR wcsTest2[13];
    wstring wstr;
}TTMP, *LPTTMP;

How big is the size of TTMP when STL classes like wstring are dynamically allocated?

Am I treating wstr as a 4-byte pointer?

I ran some tests to see the size of TTMP and got the size of the struct to be 88-bytes and two of WCHAR arrays were 26-bytes which leaves the size of wstr to be 36-bytes, but that 36-bytes does not really make sense if I were to treat the wstring as a pointer. Seems like alignment padding does not apply here since I'm only using 32-bit variables.

Also, would it be bad a practice to use ZeroMemory api on structs with STL? I've heard from someone that it is not safe to use the api, but the program ran fine when I test it

vaska11
  • 179
  • 1
  • 10
  • `ZeroMemory` is ok for POD types but you never know how non-POD stuff manages its fields so the closest safe C++ equivalent to it is probably `std::uninitialized_value_construct_n` from C++17. – Big Temp May 15 '20 at 03:14
  • *but the program ran fine when I test it* -- Change the code. You're invoking undefined behavior by using `ZeroMemory` on such a `struct`.. – PaulMcKenzie May 15 '20 at 04:01

1 Answers1

1

sizeof(WCHAR[13])=26, which is not an even multiple of 4 or 8, so alignment padding would account for a few bytes (unless you set the struct's alignment to 1-2 bytes via #pragma pack(1) or #pragma pack(2) or equivalent).

But, std::(w)string is much more than just a single pointer. It may have a few pointers in it, or at least a pointer and a couple of integers, which it uses to determine its c_str()/data(), size() and capacity() values. And it may even have an internal fixed buffer for use in Small String Optimization, which avoids dynamic memory allocation of small string values (this is likely true in your situation). So, at a minimum, a std::(w)string instance could be as few as, say, 8 bytes, or it could be as many as, say, 40 bytes, depending on its internal implementation.

See Exploring std::string for more details.

In your case, sizeof(std::wstring) is likely 32 (that is what gcc uses, for instance). So, 88-26-26-32=4, and those 4 bytes could easily be accounted for by alignment padding.

And yes, ZeroMemory() would be very bad (ie, undefined behavior) to use on a struct containing non-POD members.

Remy Lebeau
  • 454,445
  • 28
  • 366
  • 620