- ベストアンサー
引数の渡し方について
引数の渡しかたが悪いのかどうしてもうまく行きません。 何が悪いのでしょうか? 呼び出し元では文字列のポインタだけを渡して(プログラム中の第3引数) 呼び出し先でその文字列に値を設定しようとしています。 呼び出し元の変数宣言・・・ char pcImagePonit[65535]; 呼び出し元の関数 bRet = ReadPhysicsData(pcImagePonit); 呼び出し先の関数宣言 int ReadPhysicsData(char *sData) char nBufferB[65536]; 呼び出し先で値を設定 memcpy(sData, nBufferB, sizeof(nBufferB)); です。 呼び出し元で65535バイト確保した変数が、呼び出し先の関数に来てsDataになった時点で1バイトになってしまっています。 65535バイト分のデータを呼び出し先の関数内でセットしたいのですがどのようにしたら良いのでしょうか??
- みんなの回答 (10)
- 専門家の回答
質問者が選んだベストアンサー
問題なかったわけですね(笑) 「何で呼び出し先の関数でsDataの値が1バイトしか表示されないのか」は、ポインタだけ渡されても、デバッガには、ほんとは何バイトの領域なのかわからないからじゃないですか?プログラムの実行を追っているのだから、賢いデバッガならわかるでしょうけど。。。なので、null ポインタじゃなければ、1バイトは必ず確保されていると仮定して、1バイト分表示しているのでしょう。
その他の回答 (9)
- mikaemi
- ベストアンサー率50% (33/65)
C99 だと可変サイズの配列指定ができるので、 void func(size_t n, char data[n]) { ... } としておいてやれば、ポインタを渡しても、 デバッガは n バイト表示してくれるかもしれませんね^^
- shirayukix
- ベストアンサー率43% (90/207)
ANo.1, 5, 7の人です。 解決したようですね。 Visual Studio 2005のデバッガが、 sDataがcharへのポインタなので、指す先が1バイトのcharだと思いこんでいるように思えます。 デバッガには、sDataが何バイトの配列を指してるか分からないのでしょう。
お礼
何度も回答ありがとうございました。 理解を深めることが出来勉強になりました。
- shirayukix
- ベストアンサー率43% (90/207)
ANo.1とANo.5の人です。 sDataは本当に1バイトだと思いますか? 以下のソースの実効結果がどうなるか自分なりにちゃんと考えてから実行してみてください。 #include <stdio.h> #include <string.h> int main() { char pcImagePonit[65536] = ""; int bRet; printf("== before2 ==\n"); printf("pcImagePonit = %s\n", pcImagePonit); bRet = ReadPhysicsData(pcImagePonit); printf("== after2 ==\n"); printf("pcImagePonit = %s\n", pcImagePonit); return 0; } int ReadPhysicsData(char *sData) { char nBufferB[65536] = "hogehoge"; printf("== before ==\n"); printf("sData = %s\n", sData); printf("nBufferB = %s\n", nBufferB); memcpy(sData, nBufferB, sizeof(nBufferB)); printf("== after ==\n"); printf("sData = %s\n", sData); printf("nBufferB = %s\n", nBufferB); return 0; }
- mikaemi
- ベストアンサー率50% (33/65)
「呼び出し元で65536バイトの変数を渡しているのですから、 呼び出し先でも65536バイトの変数が確保されるのかと思う」という 意味がよくわからない。「呼び出し元で確保した領域とは別に、 そのポインタを渡して関数を呼び出したら、呼び出し先でも 呼び出し元で取った領域と同じサイズの領域が新たに確保される」 という意味ですか?そういう意味なら、「新しく領域は確保されません」よ。
お礼
一応渡しているのはポインタで、呼び出し先の関数でそのポインタで示された領域を直接編集しているという認識で居ます。合ってますでしょうか?? 今回のはデバッグで呼び出し先にカーソルが移った時、呼び出し先の sDataのデータがデバッガでうまく見れなかったので何か間違っているのか?と思って質問してしまった次第です。。 呼び出し先のsDataはポインタを渡されただけなので1バイト分しか デバッガに表示されないという事で良いでしょうか? 引数、ポインタ等、こんがらがっていましたが、今回の質問でだいぶ整理された気がします。 何度も回答ありがとうございました。
- shirayukix
- ベストアンサー率43% (90/207)
ANo.1の人です。 どうして完全なソースを示さないんですか? これの実行結果がどうなるか分かります? #include <stdio.h> int main() { char pcImagePonit[65536]; int bRet; bRet = ReadPhysicsData(pcImagePonit); return 0; } int ReadPhysicsData(char *sData) { char nBufferB[65536]; printf("size=%d\n",sizeof(sData)); return 0; }
お礼
すいません。ソースはとてつもなく長かったので 必要と思われる部分だけ自分で勝手に編集して記述しました。 ソースまで提示いただいてありがとうございます。 答えは4バイトでしょうか? 今回自分が1バイトといっていたのはsizeofでの値ではなく、 デバッガのウォッチウィンドウで見た配列の数?の事です。 とてつもなく紛らわしかったですね。すいません。 回答ありがとうございました。
- mikaemi
- ベストアンサー率50% (33/65)
ReadPhysicsData(char *sData) の memcpy() が終わったあとで、 sData[100] == nBufferB[100] とか sData[200] == nBufferB[200] とかは成立しているんでしょ? ReadPhysicsData() から戻ったときに、呼び出し元で、 pcImagePoint[100] などに本当に nBufferB[100] の値が入ってないのですか?そうだとしたら、memcpy() のバグなのかな??しかし、まさかねぇ。。
お礼
すいません。 結論から言うと解決しました。 戻った後の関数で、ReadPhysicsDataにしっかりnBufferBの値が入っていました。 というかもともと問題なかったようです。 呼び出し先の関数でsDataがうまく表示されなかった為でした。 ただ、何で呼び出し先の関数でsDataの値が1バイトしか表示されないのかはわかりませんが、、 VS2005.netを使用しているのですがそのせいなのでしょうか?? 総括すると、デバッグでの表示がおかしかっただけで、データはちゃんと確保されていてコピーされていたことになります。 ウォッチウィンドウで見ると、nBufferBやReadPhysicsDataは、縦に65536バイト分ズラーっと値が閲覧出来ますが、sDataだけそのようにならず、最初の1バイト分しか見えていませんでした。。 どうもお騒がせしました。。
- mikaemi
- ベストアンサー率50% (33/65)
int func(char a[100]) { return sizeof(a); } としても、func() から 100 が返ってこないというような意味? 仮引数はポインタになっちゃうから 100 ではなく、 sizeof(char *) の値になるんですけど、1 はおかしいですね。 4 くらいは返ってきそうだし。。 ひょっとして、デバッガは、文字列としてみていて、 ちょうど2バイト目に '\0' が入ってるだけってことはないですか?^^
お礼
sizeof(sData) の値は4が帰ってきます。 1バイトしかないというのは、配列(文字列)が1つ(1バイト)しか確保されていないという意味です。 本来は65536バイト分の配列(文字列)が確保されていて欲しいのです。 呼び出し元で65536バイトの変数を渡しているのですから、 呼び出し先でも65536バイトの変数が確保されるのかと思うのですが、、
- mikaemi
- ベストアンサー率50% (33/65)
65536 と 65535 と1バイト違うのが気になりますが^^ それをきちんとあわせれば問題なさそうですよね。 「sDataになった時点で1バイトになってしまう」とは、 どうして1バイトとわかったのですか? それと、「プログラム中の第3引数」ってなんでしょ??
お礼
すいません。65536と65535の違いは書き間違いでした。これと疑問とは関係ないです。。 どうして1バイトになってしまっていると思ったかといいますと、デバッグで呼び出し先の関数に来た時に、 sDataのサイズが1バイトになってしまっているのです。 ※ウォッチウィンドウで見ました。 呼び出し元の変数 pcImagePonit は65536バイトの配列?になっています。 ※プログラムの第3引数はpcImagePonit の事です。書き間違えました。。
- shirayukix
- ベストアンサー率43% (90/207)
1バイトだという根拠を簡単なソースで示してください。
お礼
呼び出し先の関数に来た時点で、sDataの値(というかサイズ?) が1バイトになってしまっているのです、、 ですので memcpy(sData, nBufferB, sizeof(nBufferB)); でコピーしようにも、 sDataは1バイト、nBufferBは65536バイトになり、 先頭の1バイト分しかコピーされていません。。
お礼
なるほど。ポインタ変数についてとても勉強になりました。 ありがとうございました。