• ベストアンサー

HOSTENT構造体を宣言する必要はないのですか?

chirubouの回答

  • chirubou
  • ベストアンサー率37% (189/502)
回答No.1

OS が分からないのですが、以下 Linux と仮定して。 参考 URL に Linux の man page を示しました。ここに書いてあるように、gethostbyname() は内部に static 宣言された struct hostent の構造体へのポインタを返します。あるいは、実装によってそういう場合があるので、例えば、帰って来た struct hostent を free() する、なんてことはしてはいけません。 さらに、この仕様は pthread 等で並行的に動作する場合、正しい動作が保証されません。このため Linux では gethostent_r() という関数があって、再帰呼び出しを可能にしています。ただし、この関数は、元の gethostent() をベースにしているので使い難いのが難点です。 Linux というか Unix には仕様自体が古くて、最近のマルチスレッドでは使う事ができない関数というのがいくつか存在します。たとえば strtok() もそのひとつです。これらの関数では関数内部の static 変数に状態を保存してしまっていますので、再帰呼び出しができない構造になっているのです。

参考URL:
http://www.linux.or.jp/JM/html/LDP_man-pages/man3/gethostbyname.3.html
fukugoo07
質問者

お礼

ありがとうございます。 猫でもわかるシリーズをC言語編,Windows編,ネットワーク編と読み進めてきた初心者です。VC++を使うつもりです。 ということは,呼び出されたgethostbyname関数が構造体を静的に宣言して,その構造体へのポインタを返し,それはstaticなものなので,おおもとのmain関数が終了するまで値を保持し続けるという理解でよいのでしょうか。 マルチスレッドのことはよくわからないですが,gethostbyname関数は,一つの同一のHOSTENT構造体にデータをセットするので,複数のスレッドからgethostbyname関数を呼び出すと,それぞれが関数を呼び出すたびに異なる値が構造体にセットされ,とんでもないことになるということですか。 なんとなくわかったような気がします。ありがとうございました。

関連するQ&A

  • ファイルのデータを構造体に代入する方法

    学習し始めてから時間が経ちましたが、まだ初心者のまま・・・少しずつ頑張っている状態の者です。 今回はタイトルのことで御質問させてください。 関数Read(自己作成)でcsvファイルの内容を読み取り、読み取ったデータを用意しておいた構造体の変数ポインタを利用して代入しようと試みているのですが・・・要領がつかめません。 それで気になったのですが、読み込んだファイルを用意しておいた構造体に入れるにはどんな方法があるかよろしければご教授下さい。 私としてはforを使ったやり方があるのなら是非見本を見せてほしいのですが・・・ ちなみに、私が考えていたプログラム案は以下の通りです。 構造体にはcsvファイル・1レコード分の情報が入る構成。 構造体と読み取るファイルの構造は酷似しているが構造体全てに入る情報でない場合がある。 構造体には必要な分、配列領域を確保する ファイルの先頭アドレスはファイルポインタに代入。 構造体の先頭アドレスはポインタ変数に代入。   main関数とは別の関数の引数に2つのアドレスをコピー。 ★ そこでファイルデータを構造体へ代入しmainに戻って出力する。    その関数での戻り値は特になし(成功したら0・・・と考えていたのですが使い道が今のところはreturnだけです) ★で特に悩んでいるので、よろしくお願い致します。

  • 構造体の宣言

    下記のように構造体の宣言をした所、 struct B_PARAM test; 「`test' の領域サイズがわかりません」というエラーになってしまいました。この構造体を宣言し、値を入れていこうとしています。 ヘッダファイルに構造体の形は定義してあるのですが、 構造体の中に構造体があるからでしょうか? またこの構造体を正しく宣言するにはどうすればいいのでしょうか?

  • 不正な構造体の演算

    ある構造体を戻り値として関数からかえして、変数に代入すると不正な構造体の演算というエラーになります。 これは、どういったことが原因と考えられますか?

  • 関数 構造体 ポインタ

    番号、名前、年齢を一組とした構造体の変数をmain関数で宣言し、そのアドレスを副関数に引き渡す。副関数で従業員番号、氏名、年齢を入力し、main関数に戻る。main関数で構造体の内容を表示する。 困ってます、ポインタがどうにも理解できません。

  • ポインタ 構造体 関数

    番号、名前、年齢を一組とした構造体の変数をmain関数で宣言し、そのアドレスを副関数に引き渡す。副関数で従業員番号、氏名、年齢を入力し、main関数に戻る。main関数で構造体の内容を表示する。 困ってます、ポインタがどうにも理解できません。

  • プロトタイプ宣言について

    C言語で関数を作成しプロトタイプ宣言するときの質問です。 関数実体の引数に構造体のポインタを宣言します。 プロトタイプ宣言には,構造体のポインタを宣言したのと同じ位置にvoid *を宣言します。 関数実体とプロトタイプ宣言は,異なるファイルです。 このように作成した関数は,VC++2008では,コンパイルできるのですが, なぜ関数実体の宣言とプロトタイプ宣言の型が異なるのにコンパイルできるのでしょうか? また,この関数を別ファイルの関数から呼び出した場合,正しく引数を理解し,正しく処理されます。 これは,言語仕様として正しい書き方なのでしょうか? それとも環境依存の書き方なのでしょうか? ご存知の方がいましたらお答えお待ちしています。

  • ポインタを使って構造体の配列を戻り値にするには

    関数の戻り値を構造体の配列(アドレスを受け渡しを利用して)にしたいのですがうまくゆきません。 以下のプログラムではコンパイルはできるのですが、 a0 = 2 a1 = 4198512 a2 = 4329332 と表示されてしまいa1,a2がうまくゆきません。 ********************************************* #include<stdio.h> struct test{ int a; }; struct test *func(void); void main(void) { struct test *data;//構造体ポインタ int i; data = func(); //ポインタにtest関数の戻り値(アドレス)を代入 for(i=0;i<=2;i++){   printf("a%d = %d\n",i,(data+i)->a); //構造体要素を表示 } } struct test *func(void) { struct test data[3]={1,2,3}; //構造体配列を定義 return (&data[0]); //構造体配列の先頭アドレスを返す } ************************************************* test関数から受ける取ったアドレス(&data[0])をポインタ(data)に代入して1づつずらして表示させれば a0=1,a1=2,a=3 となると思ったのですがどこが間違っているのでしょうか? よろしくお願いします。

  • 構造体の宣言方法について

    構造体の宣言で ヘッダーファイルに struct RAM rom_AAA[20] を宣言 Cソースファイル(上記のヘッダーファイルをインクルードする)に struct RAM { struct BBB *CCC } を宣言 とした時 rom_AAA[20]と*CCC(BBBアドレス)はリンクしてる状態になるのでしょうか? 構造体の一部の定数テーブルを参照するために 間単にポインタ使ってグルグル回したいのですが、同じものをアクセスしてる事にならないでしょうか?

  • 構造体の代入

    構造体の比較はパディング領域が存在しうるので一つ一つの要素を比較する必要がありますが、 構造体を代入するのは、そのまま代入して問題ないでしょうか? それとも1要素ずつ代入すべきでしょうか。

  • Cで関数とポインタと構造体の表現法

    C言語の関数で 構造体・共用体の入った配列を関数にポインタで送りたいと思うのですが上手くいきません プロトタイプ宣言とメイン文での表現・関数そのものでの表現 が詳しく知りたいのですがサイトまたは記述方を教えてください。 上記の条件で ポインタは*をつけるつけない 関数で引数はどうやって選ぶのか 構造体名などはどのように表現すればいいのか などの見分けがいまいちつかないので悩んでいます。