次のコード スニペットは、実行中の SW を抽出して簡略化したものです。リバース エンジニアリングを行っています (細かな点を気にせずに問題を強調しようとしました)。
win64 マシンで次のコードをビルドすると、操作中にクラッシュが発生します。
#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;
}
いくつか質問があります:
J++
win32 プラットフォームでインデックス ( ) を 2 回インクリメントする必要があるのはなぜですか? - win32 プラットフォームは、double に対して char* ポイントを 2 回「ジャンプ」することをどのように認識していますか?- なぜ sprintf_s は、win32 の oData (コンポジション コンテナー) から正しいフィールドを選択することを知っているのでしょうか? しかし、win64ではクラッシュしますか?
これは、32 ビットと 64 ビットのポインター サイズの違いによるものだと思いますが、動作を説明するためにあなたの助けを求めています。