プロシージャの中で宣言した文字列について

解決


どら  2004-11-19 04:38:38  No: 55221

毎度です(^^;
ちょっと気になったことがあったので・・・

かなりはしょりますが・・・

kansu(char *moziretsu);

char global[12];

WinMain( ・・・・ )
{
}

WinProc( ・・・・ )
{
    char InProc[12];
    
    kansu(InProc);
    kansu(Global);

    MessageBox(NULL, Global, "グローバル", MB_OK);
    MessageBox(NULL, InProc, "プロシージャ内", MB_OK);

}

kansu(char *moziretsu)
{
    char buf[12];
    [何らかの文字列をbufに格納]
    strcpy(moziretsu, buf);
}

といったように、外部関数などで文字列を取得しようとしたときに、グローバルで宣言した変数は正常に表記されるのですが、プロシージャ内で宣言した文字列変数は、半角で「フフフフフフフフフフ・・・・」とでてしまいます。

プロシージャ内で宣言してしまうと、アドレスがずれたり、壊れたりしてしまうのでしょうか?

何やら初心者的な質問かもしれなくてごめんなさい・・・。

プロシージャ内だけで使用すればよい文字列変数を、わざわざグローバルで宣言しなければならないのがむずがゆくて・・・


tetrapod  2004-11-19 17:38:37  No: 55222

そんなことはありません。きっと、他にバグがあります。

#include <stdio.h>
void setstring(char *p) {
  strcpy(p, "Hello!");
}
int main() {
  char str[12];
  setstring(str);
  printf("%s\n", str);
  return 0;
}
まったく正常(=期待通り)です。


どら  2004-11-19 18:28:19  No: 55223

tetrapodさん

記入されたソースは、プロシージャはいっさいでてきませんが・・・
私が言っているのは、WinProcやDlgProc内で文字列変数を宣言した時の話をしているのですが・・・。

ちなみに、作成した外部関数内で、strcpyした後の文字列(私が書いた例で言うと「moziretsu」になりますが)をMessageBoxで出力すると、思ったとおりの値がでますが、プロシージャ内で宣言した文字列にその関数を使用し、MessageBoxで出力すると、おかしな表記になるということです。

全く同じ構成で、その文字列だけをグローバルで宣言すると正常に表示されます。


シャノン  2004-11-19 19:23:51  No: 55224

> 記入されたソースは、プロシージャはいっさいでてきませんが
出てきますよ。main プロシージャと setstring プロシージャが。

> 私が言っているのは、WinProcやDlgProc内で文字列変数を宣言した時の話をしているのですが
であれば「ウィンドウプロシージャ」とか「ダイアログプロシージャ」って書かないとわからないと思います。
#ちなみに WndProc では?  まぁ、関数名は自由ですが。

WinProc で、kansu() の呼び出しと MessageBox での表示は、ひとつのメッセージの処理内で行っていますか?
でない場合、InProc は WinProc が呼ばれるたびに初期化されますよ。


(noname)  2004-11-19 19:40:08  No: 55225

(;´Д`)y-~~ わからんヤシだな。
もしプロシージャだのコールバックだのが関係あんなら,
tetorapod 氏もそこらへんを指摘しただろうよ。
例外がねーわけじゃねーが,上級者でもない限り気にするもんでもねーし。

以下のコードを試してみること ( ´Д`)y-~~

#include <windows.h>
#include <string.h>

void kansu (char *moziretsu) {
  char buf[12];
  strcpy (buf, "moziretsu");
  strcpy (moziretsu, buf);
}

char Global[12];

LRESULT __stdcall WinProc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
  char InProc[12];

  if (msg == WM_NCCREATE) {
    kansu (InProc);
    kansu (Global);

    ::MessageBox (NULL, Global, "グローバル", MB_OK);
    ::MessageBox (NULL, InProc, "プロシージャ内", MB_OK);

    return FALSE;
  }

  return ::DefWindowProc(hwnd, msg, wparam, lparam);
}

int __stdcall WinMain (HINSTANCE hinst, HINSTANCE, LPSTR, int) {
  WNDCLASSEX wx = { sizeof(WNDCLASSEX), 0, WinProc, 0, 0,
    hinst, ::LoadIcon(NULL, IDI_WINLOGO), ::LoadCursor(NULL, IDC_ARROW),
    (HBRUSH)(COLOR_BTNFACE + 1), NULL, "MoziretsuTestClass", NULL };

  ATOM atom = ::RegisterClassEx(&wx);
  if (! atom) return 0;

  ::CreateWindowEx (0, reinterpret_cast<LPCTSTR>(atom), "", 0,
    0, 0, 0, 0,
    0, 0, hinst, 0 );

  return 0;
}


どら  2004-11-19 21:32:08  No: 55226

シャノンさん

> であれば「ウィンドウプロシージャ」とか「ダイアログプロシージャ」って> 書かないとわからないと思います。

・・・ですね。
大変失礼しました。

> #ちなみに WndProc では?  まぁ、関数名は自由ですが。
これもおっしゃるとおりですね(^^;
WndProcです。

> WinProc で、kansu() の呼び出しと MessageBox での表示は、ひとつのメッ> セージの処理内で行っていますか?
> でない場合、InProc は WinProc が呼ばれるたびに初期化されますよ。

それだ!!
そう言うことだったんですね〜。
一つのメッセージの処置内で行っていなかったです。

ありがとうございます。

nonameさん
私がよく分かっていないのは自分でもわかっています。
だからこそ掲示板に質問しているのでは?
言い方が少しひどいのでは・・・(T_T)


(noname)  2004-11-19 22:17:03  No: 55227

(;´Д`)y-~~ 悪かったよ。


シャノン  2004-11-19 23:23:04  No: 55228

>> WinProc で、kansu() の呼び出しと MessageBox での表示は、ひとつのメッセージの処理内で行っていますか?
>> でない場合、InProc は WinProc が呼ばれるたびに初期化されますよ。

> 一つのメッセージの処置内で行っていなかったです。

ちなみに、static 変数にしても OK です。
他にも、グローバル以外にも方法はいろいろあります。


RAPT  2004-11-20 08:09:46  No: 55229

参考までに。
デバッガ内で「フフフフ…」と表示されているのは、単にその配列変数が
未初期化であることを示しています。VC++デバッガは、デバッグモード時、
未初期化の変数を0xCC(2進数だと、11001100)で初期化するためです。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加