1

私はソケットプログラミングを勉強していますが、このコードに遭遇しました。

struct addrinfo hints, *res, *p;
int status;
char ipstr[INET6_ADDRSTRLEN];

if (argc != 2) {
    fprintf(stderr,"usage: showip hostname\n");
    return 1;
}

memset(&hints, 0, sizeof hints); 
hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
hints.ai_socktype = SOCK_STREAM;

if ((status = getaddrinfo(argv[1], NULL, &hints, &res)) != 0) {
    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
    return 2;
}

1つを除いてすべて理解しています。なぜこのコードは構造体のヒントをmemsetしましたが、*resと*pはしませんでしたか?

4

4 に答える 4

3

resポインターはgetaddrinfo関数によって設定されるため、ゼロで初期化する必要はありません。hints一方、初期化する必要があるため、構造体全体をゼロに設定してから、設定する必要がある 2 つのフィールドのみを設定します。

コードで使用pしていないため、コメントできません。

于 2012-03-22T10:23:11.283 に答える
1

getaddrinfoの説明には、

getaddrinfo() 関数は、addrinfo 構造体のリンクされたリストを割り当てて初期化し、ノードとサービスに一致するネットワーク アドレスごとに 1 つ、ヒントによって課された制限に従い、リストの先頭へのポインターを res に返します。

つまりhints、厳密に必要な情報以外は必要ありません (そうしないと、関数が望ましくない出力を生成する可能性があります)。また、関数の「実際の」結果は に返されますres。これは、 の現在の内容resが上書きされることを意味するため、関数呼び出しの前にそこに何があったかはあまり気にしません (次の場合に解釈しない限り)。関数は失敗します)。

構造体 ( など) のメンバーは、addrinfoその型の変数を宣言するときに初期化されないため、hints最初は「ガベージ」が含まれています。変数が割り当てられているメモリ内にあったものは何でも。したがって、コードはmemset、(メンバー変数を 1 つずつゼロに設定するのではなく) 簡単で高速な方法ですべてのメンバーをゼロにするように呼び出します。

于 2012-03-22T10:35:58.010 に答える
0

memset ヒントをすべて 0 にするだけなので、そうすべきではありません。また、 res と p は、 memset 呼び出し時にどの場所にも配置されないポインターのみです。

これは予期される動作です。あなたの例外を教えてください。より良いお手伝いができるようにいたします。

于 2012-03-22T10:25:01.373 に答える
0

このコードが構造体ヒントを memset したのに、*res と *p を memset しなかったのはなぜですか?

なぜなら、memset を 1 回だけ呼び出して、その memset への引数として &hints だけを渡しているからです。

memset(&hints, 0, sizeof hints);

*res と *p を memset したい場合は、最初にメモリを割り当てる必要があります。これらは唯一のポインタであるためです。次に、それらを引数として渡すことにより、それらのそれぞれに対して memset を個別に呼び出す必要があります。

于 2012-03-22T10:25:30.203 に答える