- ベストアンサー
wsprintf( ) でポインタに代入
wsprintf(p, "%d" , i); を書いたせいで、i の値が変わります。 wsprintf(p, "%d" , i); によってどんなことが起こっているのか詳しく知りたいです。 ポインタのことがまだよく分かってないんです。 #include <windows.h> LPCSTR szStr = "\n char c[255];\n char *p = \"\\0\";\n int i = 12345;\n\n switch (msg){\n case WM_LBUTTONDOWN:\n wsprintf(c, \"%d\" , i);\n wsprintf(p, \"%d\" , i);\n MessageBox(hWnd , c , \"\" , MB_OK);\n break;"; LRESULT CALLBACK WndProc(HWND , UINT , WPARAM , LPARAM); int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE , LPSTR , int){ 省略 return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd , UINT msg , WPARAM wParam , LPARAM lParam){ HDC hDC; PAINTSTRUCT ps; RECT rt; char c[255]; char *p = "\0"; int i = 12345; switch (msg){ case WM_LBUTTONDOWN: wsprintf(c, "%d" , i); wsprintf(p, "%d" , i); MessageBox(hWnd , c , "" , MB_OK); break; case WM_PAINT: GetClientRect(hWnd, &rt); hDC = BeginPaint(hWnd, &ps); DrawText(hDC, szStr, lstrlen(szStr), &rt, DT_WORDBREAK); EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return(DefWindowProc(hWnd , msg , wParam , lParam)); } return (0L); }
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。itohhといいます。 ykkw_2001さんの回答に補足します。 このソースコードを見てみると、 >char *p = "\0"; >int i = 12345; は、隣り合ったエリアを確保しているのだと思います。 (この辺はコンパイラが自動的に決めます。) *pは1バイトのエリアです。そしてiはintなので4バイトのエリアです。 そして、 >wsprintf(p, "%d" , i); では、pのアドレスから5バイト(12345を書き込むエリア)+1バイト(\0)が必要です。 (printf系の関数は最後にNULLを自動的に書き込みます。) ですから、「wsprintf(p, "%d" , i)」を実行した段階でiのエリアにも不正な書き込みが 行われてしまったのだと思いますよ。
その他の回答 (1)
- ykkw_2001
- ベストアンサー率26% (267/1014)
プログラムは全部見てないんですが・・ ここのところ、 >char *p = "\0"; char p[20]; にしたほうがいいと思います。(20は、適当に大きめにね) どうしても p をポインタ変数にしたいときは、 char s[20]; char *p; p = s; のように別途エリアを確保する。 p が指し示すメモリエリアは、"\0"(=0x00) が格納されたアドレスになっています。 >wsprintf(p, "%d" , i); で、数バイトの文字列がコピーされますので、その分を確保しておかないと、結果はおかしくなります。 ポインタを乗り越えれば、「ビギナ脱出」だと思います。 がっばってネ。
お礼
ありがとうございます。 下で教えてもらったばっかりの char *p = "\0"; が まだよく分かってなくて質問したけど、もう分かりました。
お礼
ありがとうございます。 wsprintf(p, "%d" , i); では p に6バイト必用なのに p は1バイトしか確保してないから、残り5バイトが たまたま p の次に確保されていた i のデータを 上書きしてしまったんですね。