The following code snippet is an extraction and simplification of a running SW I am reverse engineering (I tried to emphasize the problem without bothering you with all the small details).
Building the following code on a win64 machine causes crash during operation:
#include "stdafx.h"
#include <stdio.h>
#include <string>
#include <stdlib.h>
using namespace std;
struct vaArgLookAlikePtrs
{
char* pPtr[1000];
};
int _tmain(int argc, _TCHAR* argv[])
{
typedef std::basic_string<char> BasicString;
static char buffer[132000];
BasicString sFormatStr = "Var0=%s\nVar1=%.4f\nVar2=%d\n";
struct vaArgLookAlikePtrs oData;
void* pVoidPtr;
int j=0;
oData.pPtr[j] = "val0";
j++;
double dVar1 = 1.265;
pVoidPtr = (void*)(&(oData.pPtr[j]));
double* pDoublePtr = (double*)pVoidPtr;
*pDoublePtr = dVar1;
j++;// increment the buffer counter twice because doubles require 64 bits for storage (This is how it works on the 32 bit machine)
j++;
int nVar2 = 2;
pVoidPtr = &(oData.pPtr[j]);
int* pIntPtr = (int*)pVoidPtr;
*pIntPtr = nVar2;
sprintf_s(buffer,sFormatStr.c_str(),oData); // <-----
cout << buffer << "\n";
return 0;
}
I have few questions:
- Why should i increment the index (
J++
) twice on win32 platform? - how does win32 platform knows to "jump" over a char* point twice for a double? - how come sprintf_s knows to pick the right fields from oData (a composition container) on win32? but on win64 it crashes?
I assume this is somehow with pointer sizes difference between 32 bit and 64 bit, but I'm seeking your help to explain the behavior.