10
struct hostent *gethostbyname(const char *name)

请注意,hostent.h_addr_list 是一个具有不同长度的字段。

该函数如何gethostbyname实现返回指向结构的指针但不需要调用者释放资源?

R. Stevens 的著名著作 Unix Network Programming Vol 1 中使用的所有示例都不包含释放这些返回指针的代码,我认为这些不是无知的。来自 MSDN 的一个示例也做了相同的使用示例

4

5 回答 5

5

您链接到的man页面包含答案:

当非 NULL 时,返回值可能指向静态数据,见下面的注释。

稍后:

函数 gethostbyname() 和 gethostbyaddr() 可能会返回指向静态数据的指针,这些指针可能会被以后的调用覆盖。

于 2012-07-18T15:07:49.123 回答
3

假设一个实现想要处理任意大的地址列表,它可以做这样的事情:

struct hostent *gethostbyname(const char *name) {
    static struct hostent *results = 0;
    static size_t resultsize = 0;
    size_t count = get_count_of_addresses(name)
    if (count > resultsize) {
        struct hostent *tmp = realloc(results, N * count + M);
        if (tmp) {
            results = tmp;
            resultsize = count;
        } else {
            // handle error, I can't remember what the docs say
        }
    }
    fill_in_hostent(results, name);
    return results;
};

或者,sockets 库可以results在退出时释放一些东西(例如安装atexit处理程序),以避免调试工具报告内存泄漏。

我忽略了地址数量在调整结构大小和填充结构之间可能发生变化的可能性——实际上,您会取回 DNS 结果,然后对其进行处理,因此这是不可能的。我将其保留为两个单独的调用,以避免为 DNS 结果引入伪代码表示。

于 2012-07-18T15:20:36.507 回答
2

可能指向静态内存。如果要保留多个结果,则需要对其进行深层复制。不是浅拷贝,因为该结构本身包含指针。

注意线程安全。

于 2012-07-18T15:08:45.647 回答
1

它可能指向静态内存,即每次调用都使用相同的指针。

于 2012-07-18T15:04:27.677 回答
0

MS 告诉我们https://msdn.microsoft.com/en-us/library/windows/desktop/ms738524%28v=vs.85%29.aspx

The memory for the hostent structure returned by the 
gethostbyname function is allocated internally by the 
Winsock DLL from thread local storage. Only a single 
hostent structure is allocated and used, no matter how 
many times the gethostbyaddr or gethostbyname functions 
are called on the thread

所以它在 Windows 上是线程安全的,但是......

它已从 POSIX 中删除,man7.org 告诉我们,在 Linux 上,主机名语言环境不是线程安全的。http://man7.org/linux/man-pages/man3/gethostbyname.3.html

..MS 告诉我们

The gethostbyname function has been deprecated 
by the introduction of the getaddrinfo function

不幸的是,替换(getaddrinfo,大多数平台上的线程安全)不是套接字 1.x 的一部分,并且在旧平台上不可用。

于 2015-08-07T03:26:33.820 回答