getaddrinfo addrinfo результат в стеке или куче - PullRequest
3 голосов
/ 24 марта 2011

Я немного запутался, по крайней мере. Вызов getaddrinfo () «обновляет» указатель на структуру addrinfo, все хорошо, когда я собираюсь использовать addrinfo в той же области (этой функции), но что произойдет, если я скопирую структуру в другую (назначив ее).

Пожалуйста, помогите мне понять основные принципы (не ищите совета для альтернативных подходов).

Поправь меня, если я ошибаюсь: a) getaddrinfo () требует указатель на struct-pointer для addrinfo. b) getaddrinfo создает структуру addrinfo в текущей области действия функции и обновляет указатель, необходимый в a)

Теперь мой реальный вопрос: я хотел бы хранить это аддринфо в другом месте. Использование присваивания другому указателю не делает глубокого копирования, и после функции все указатели становятся недействительными?

Лучше приведите чрезвычайно упрощенный пример:

void GetAddrInfo(struct addrinfo *update)
{
    struct addrinfo *res;
    getaddrinfo(xx,xx,xx,&res);

    //is this save? After this 'scope' ends all pointed fields are invalid?
    //this doesn't copy the linked list ai_next.
    *update=*res; 
}

Непосредственное использование & update для getaddrinfo, похоже, не работает, потому что проблема остается: исходная структура уничтожается после окончания области действия функции.

Любой, кто сможет дать мне более глубокое понимание здесь (пожалуйста, объясните, что создается и где уничтожается, где складывается, куча вся информация приветствуется)

Ответы [ 2 ]

6 голосов
/ 24 марта 2011

исходная структура уничтожается после окончания области действия функции

Нет, указатель структуры уничтожен. Остальные данные все еще в куче. Это будет утечка памяти, если вы не позвоните freeaddrinfo(), когда закончите с результатом.

Я хотел бы хранить это аддринфо в другом месте

Поскольку данные все еще существуют, не стесняйтесь копировать указатель; нет необходимости в глубокой копии. Из вашего примера:

void GetAddrInfo(struct addrinfo **update)  /* pointer to pointer */
{
    struct addrinfo *res;
    getaddrinfo(xx,xx,xx,&res);
    *update=res;  /* save the pointer to the struct */
}

Вы бы просто вызвали эту функцию с помощью:

struct addrinfo *mycopy;
GetAddrInfo(&mycopy);
1 голос
/ 24 марта 2011

getaddrinfo выделяет список addrinfo структур и дает вам указатель на заголовок списка.Вы освобождаете всю выделенную память, передавая этот указатель на freeaddrinfo, когда закончите.

То, что вы делаете, достаточно безопасно, но утечка памяти.

void GetAddrInfo(struct addrinfo **update)
{
    getaddrinfo(xx,xx,xx,update);
}


addrinfo * myai;
GetAddrInfo(&myai);
freeaddrinfo(myai)

Этот подход не приведет к утечке памяти - вы просто получаете указатель на заголовок списка addrinfo.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...