#include <stdio.h>
#include <netdb.h>
#include <stdlib.h>
/// Global declarations:
const char *hostNameOrIPAddress;
const char *serviceOrPortNum;
const struct addrinfo *hints;
struct addrinfo **resultOfGetAddrInfo;
int socketFd;
int fillUpStructSockaddrIn ()
{
hostNameOrIPAddress = "127.0.0.1";
serviceOrPortNum = "1234";
hints = malloc (sizeof (struct addrinfo*) * 10);
hints->ai_family = AF_UNSPEC;
hints->ai_socktype = SOCK_STREAM;
hints->ai_flags = AI_PASSIVE;
if (getaddrinfo (hostNameOrIPAddress,
serviceOrPortNum,
hints,
resultOfGetAddrInfo) != 0)
// Indicate some error.
return 1;
return 0;
}
int main ()
{
if (fillUpStructSockaddrIn() != 0)
return 1;
socketFd = socket (AF_INET, SOCK_DGRAM, 0);
return 0;
}
**
**
$ gcc server.c
server.c: In function ‘fillUpStructSockaddrIn’:
server.c:35:3: error: assignment of member ‘ai_family’ in read-only object
hints->ai_family = AF_UNSPEC;
^
server.c:36:3: error: assignment of member ‘ai_socktype’ in read-only object
hints->ai_socktype = SOCK_STREAM;
^
server.c:37:3: error: assignment of member ‘ai_flags’ in read-only object
hints->ai_flags = AI_PASSIVE;
^
请参阅此处getaddrinfo
的声明:
http://linux.die.net/man/3/getaddrinfo
需要const struct addrinfo *hints
。
我应该如何填写其中的值?
如果我不喜欢malloc,我会遇到分段错误。
答案 0 :(得分:1)
声明
const struct addrinfo *hints;
将hints
声明为指向常量结构的指针,即一个只读且无法更改的结构。
除此之外,你分配hints
是错误的,因为你分配了十个指针(40或80个字节取决于你是否在32位或64位平台上)。您应该分配sizeof(*hints)
个字节。
此外,malloc
调用不会初始化它分配的内存,这意味着您未初始化的成员字段中的数据将是不确定的,getaddrinfo
调用将导致{ {3}}因此。首先清除结构,方法是使用undefined behavior或使用calloc
。
实际上你根本不需要动态分配该结构,只需将其声明为普通的局部变量,并使用address-of运算符&
传递指针:
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
getaddrinfo(..., &hints, ...);
现在你有一个内存泄漏,因为你没有释放分配的内存。使用结构(而不是指向结构的指针),您不必担心这一点。
答案 1 :(得分:1)
您将hints
定义为指向常量结构的指针
const struct addrinfo *hints;
因此,您不要更改此结构和此代码的数据成员
hints->ai_family = AF_UNSPEC;
hints->ai_socktype = SOCK_STREAM;
hints->ai_flags = AI_PASSIVE;
错了。
即使结构不是常量,上面的语句也是错误的,因为你没有为结构分配内存。您为具有未定义值的指针分配了内存。所以程序有不确定的行为。
还有这些陈述
if (getaddrinfo (hostNameOrIPAddress,
serviceOrPortNum,
hints,
resultOfGetAddrInfo) != 0)
// Indicate some error.
return 1;
return 0;
至少可以代替
return getaddrinfo (hostNameOrIPAddress,
serviceOrPortNum,
hints,
resultOfGetAddrInfo) != 0;
程序不会删除已分配的内存。