GetTextMetricsW causing memory corruption

I have been converting our ANSI product to UNICODE, and today during testing I was getting Run-Time Check Failure #2 - Stack around the variable 'tm' was corrupted. error messages.

Turned out it was this code:

TEXTMETRICW tm;
GetTextMetricsW( hDC, &tm ) ;

I isolated the code into a test function, which then became two functions:

void TestFuncA(HDC hDC)
{
  TEXTMETRICA tm;
  void* p = &tm;
  memset(&tm, -1, sizeof(tm) );
  GetTextMetricsA( hDC, &tm ) ;
}

void TestFuncW(HDC hDC)
{
  TEXTMETRICW tm;
  void* p = &tm;
  memset(&tm, 0, sizeof(tm) );
  GetTextMetricsW( hDC, &tm ) ;
}

For TestFuncW the sizeof(tm) is 57 bytes, yet GetTextMetricsW is over writing 60, as seen by the Memory debugging window, whereas for TestFuncA sizeof(tm) is only 53 bytes, and GetTextMetricsA overwrites only 53 bytes.

I then created a brand new Win32 Windows C++ application, and placed my test code into this, and strangely enough, for TestFuncW the sizeof(tm) is 60 bytes, yet GetTextMetricsW is over writing 60, and for TestFuncA sizeof(tm) is only 56 bytes, and GetTextMetricsA overwrites only 53 bytes.

Hazarding a guess, “that it is the fact the original product has Struct Member Alignment (same as #pragma pack() ) set to 1 Byte (/Zp1)”, I changed this from the default to 1, and tada!

Now my new project crashes also.

Lesson for others, avoid Struct Member Alignment across full projects.

Lesson for me, I now have weeks of work to unravel the effects/impact of why it was set to 1 in the first place (old legacy code and lazy developers)