• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ポインタの引数について。)

ポインタの引数について

このQ&Aのポイント
  • C言語初心者の質問者がポインタの引数についての理解について尋ねています。
  • 質問者は既存のプログラムを修正しているが、ポインタの概念が理解できておらず、修正した箇所がうまく動作しないと困っています。
  • 質問者はポインタを使ってrecvで受け取った内容を動的に変更する方法について質問しています。

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

そういうものは省略されると想像するしか無いので、正しいかどうかの判断はできないのですが... 変更点は本当にここだけですか?(関数subのr_msgが構造体かunsigned char*かの違い) 変更前と後のソースファイル全部をdiffで比較しても、変更点はここだけですか? Cのポインタの性質を考えれば、それだけの変更なら動作に違いはないはずです。 ポインタ自体には、実体が何型か、などという情報は含まれていないのですから。特に今回はchar*にキャストしているので、元が何型であったとしても、char*として扱われます。 また、recvは受け取るための関数であって、元に何が書かれていようが関係なく、受け取ったデータをそのポインタに順番に書き込むだけのはずです。 他に変わったんじゃないですか? 通信の仕様が変わって、バッファを可変にする必要がでてきたので、プログラムを変更してるのではないですか? 試しに、変更前のプログラムで 関数subの r_msg だけ変更して実行してみてください。 struct msg* r_msg; r_msg=malloc(buflen) ; sub_recv(s,r_msg,time) ; 以下、 r_msg.XXX → r_msg->XXXに変更 そちらでは正常に動作するはずです。

robarobagoo
質問者

お礼

kmeeさん ご回答ありがとうございます。 省略して申し訳ありませんでした。 >通信の仕様が変わって、バッファを可変にする必要がでてきたので、プログラムを変更してるのではないですか? 通信の仕様は変えていないと思います。 実際は send() で送るバッファも struct msg の構造体だったのですが、これを buflen で malloc した配列に変更しています。 修正しているのは自分だけなので、他は特に変更点はないはずです。 なので、send() 側を可変にしている状態で、recv() 側(今回質問させて頂いているソース)を修正前のソースですと、 struct msg 構造体でとってあるバッファ以下のものは受信できるのですが、当然それ以上だとプログラムが終了します。 なので、質問のような修正を行っております。 単純に recv() の動きを見たいと思い、以下のような事を試してみました。 void sub_recv(s,*msg,time) { unsigned char *pack; int cc; int len; char buf[buflen]; //recv() 確認用バッファ。単純化する為に配列。 pack = (unsigend char *)msg /*ここの代入は無意味と思いますがなくしても同様の結果のなので残してます。*/ cc = recv(s, buf, len, 0); //そのまま recv() に配列 buf を渡す if(cc < 0) return(cc); ・・・ } 他の部分で落ちるにしてもとりあえず recv() からは 1~len の値が返ってくるだろうと 期待したのですが、これでも cc には -1 が入ってしまうようなので、困惑しています。 アドバイス頂きましたものを参考に試してみたいと思います。 ありがとうございます。

その他の回答 (1)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

まず > void sub_recv(s,*msg,time) いまどき、こんな宣言は使いません。 別にプロトタイプ宣言がされているのでしょうか? それとも、コンパイラやライブラリが古い仕様なのでしょうか? > int len; とありますが、そのlenに値が設定されていません。 ここに載せるときに省略しただけでしょうか? そうでないなら、lenの値は不定です。何が入っているかわかりません。 len = 1 となっている可能性も0ではありません。recvの第三引数は、読み取る最大長を指定するものなので、 1バイトしかとれない、ということも有り得ます。 > extern int buflen; > void sub() ... > r_msg=(char *)malloc(sizeof(char)*buflen ); こういうのって、void sub(int buflen) と宣言して、引数で渡すのが普通で、externの変数を呼ぶなんてことは、それの方が明らかに便利、というときでもないかぎりやりません。 で、ここで確保した長さであるbuflenは、recvの第三引数として使いたいものではないでしょうか? > void sub_recv(s,*msg,time) → void sub_recv(int s, struct msg *msg,int time,int len) とでも宣言して、 sub_recv(s,r_msg,time,buflen) とでも呼び出すのがいいのではないでしょうか? > return(cc); void型関数で値を返してはだめでしょ。 void型ならretrunだけにする。 値を返すなら、適切な型にしましょう。

robarobagoo
質問者

補足

kmeeさん 早速のご回答ありがとうございます。 >void sub_recv(s,*msg,time) ですが、これは int sub_recv(SOCCKET s, unsigned char *msg, int time) の間違いです。プロトタイプ宣言を忘れてしまい申し訳ありません。 質問を書いてるうちにccを戻そうと書いたところ、voidの修正も忘れてました。 >とありますが、そのlenに値が設定されていません。 >ここに載せるときに省略しただけでしょうか? それぞれの変数には任意の値が入っていると仮定して下さい。説明不足で申し訳ありません。 ご指摘有り難うございます。 pack = (unsigend char *)msg もセミコロンが抜けたりしていてすいません。 >こういうのって、void sub(int buflen) と宣言して、引数で渡すのが普通で、externの変数を呼ぶなんてことは、それの方が明らかに便利、というときでもないかぎりやりません。 おっしゃることは承知ですが、このbuflenをexternで使用したいと思っています。 ご提案のようにsub_recv()にbuflenを引数で渡す場合には、sub()内でなくそちらでmallocした方がいいということでしょうか? 今回伺いたかったのが、r_msgとmsgとpktの関係の部分についてだったので、他の部分を省いてしまったりでわかりずらく申し訳ありません。 なぜ修正後のものだとrecv()から-1が返ってきてしまうのか。そこが知りたいです。 r_msgに適当に文字列を入れてsub_recv()の中で*msgも*pktも期待値が取れるので、アドレスはちゃんと渡せているように思うのですが。 因に、lenに入る値はbuflenよりも小さいものと仮定してください。 わかりにくい質問で大変恐縮ですが、何卒宜しくお願いします。

関連するQ&A

専門家に質問してみよう