Смущенный о memset - PullRequest
       33

Смущенный о memset

0 голосов
/ 22 марта 2012

Я изучаю программирование сокетов, и я столкнулся с этим кодом.

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;
}

Я все понимаю, кроме одного. Почему этот код memset'а подсказывает структуру, а не * res и * p?

Ответы [ 4 ]

3 голосов
/ 22 марта 2012

Указатель res заполняется функцией getaddrinfo , поэтому его не нужно инициализировать нулем. hints с другой стороны, необходимо инициализировать, следовательно, установить всю структуру на ноль, а затем установить только два поля, которые нужно установить.

Поскольку вы не используете p в своем коде - я не могу это комментировать.

1 голос
/ 22 марта 2012

В описании getaddrinfo говорится, что

Функция getaddrinfo () выделяет и инициализирует связанный список структур addrinfo, по одному для каждого сетевого адреса, который соответствует узлу и услуге,с учетом любых ограничений, налагаемых подсказками, и возвращает указатель на начало списка в рез.

. Это означает, что вам не нужна никакая другая информация в hints, кроме строго необходимой (в противном случаефункция может выдавать нежелательный вывод).Кроме того, «реальный» результат функции возвращается в res, что означает, что текущее содержимое res перезаписывается, поэтому вам все равно, что там было до вызова функции (пока выне будет интерпретировать это, если функция завершится ошибкой).

Поскольку члены структуры (например, addrinfo) не инициализируются каким-либо образом при объявлении переменной этого типа, hints изначально содержит «мусор»"- что бы ни случилось в памяти, где размещена переменная.Таким образом, код вызывает memset для обнуления всех членов простым / быстрым способом (в отличие от установки переменных-членов в ноль один за другим).

0 голосов
/ 22 марта 2012

Почему этот код memset использовал подсказки структуры, а не * res и * p?

Поскольку вы вызываете memset только один раз и передаете только & hints в качестве аргумента этому memset.

memset(&hints, 0, sizeof hints);

Если вы хотите использовать memset * res & * p, сначала вам нужно выделить память для того же, что они являются только указателями, а затем вам нужно отдельно вызвать memset для каждого из них, передав их в качестве аргументов.

0 голосов
/ 22 марта 2012

Это не должно быть, поскольку вы только намекаете на memset всем 0. Также res и p являются только указателями, не находящимися в каком-либо месте во время вызова memset.

Это ожидаемое поведение. Дайте мне знать, что вы исключение, и я смогу помочь вам лучше.

...