C 错误:在只读对象中分配成员ai_族

C 错误:在只读对象中分配成员ai_族,c,linux,sockets,gcc,C,Linux,Sockets,Gcc,^ 请参见此处的getaddrinfo声明: 它需要一个常量结构addrinfo*提示。 我应该如何在其中填充值 如果不使用malloc,则会出现分段错误。声明 $ 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

^

请参见此处的
getaddrinfo
声明:

它需要一个
常量结构addrinfo*提示
。 我应该如何在其中填充值

如果不使用malloc,则会出现分段错误。

声明

$ 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;
提示
声明为指向常量结构(即只读且无法更改的结构)的指针


除此之外,您分配的
提示
是错误的,因为您分配了十个指针(这是40或80字节,取决于您是在32位还是64位平台上)。您应该分配
sizeof(*提示)
字节

另外,
malloc
调用不会初始化它分配的内存,这意味着您未初始化的成员字段中的数据将是不确定的,因此,
getaddrinfo
调用将导致不确定。首先使用或清除结构


实际上,您根本不需要动态分配该结构,只需将其声明为正常的局部变量,并使用运算符
的地址传递指针:

const struct    addrinfo *hints;

现在,由于没有释放分配的内存,内存泄漏。使用结构(而不是指向结构的指针)您不必担心这一点。

您将
提示定义为指向常量结构的指针

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, ...);
因此,您不会更改此结构和此代码的数据成员

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;

并且程序不会删除分配的内存。

不要将它们定义为constyes,我可以看到,但是“addrinfo”的参数需要该声明。我遗漏了什么?@theindependentquarius是的,这是因为
getaddrinfo
没有改变结构,因此编译器可能会在该函数和调用中进行一些额外的优化。但是,必须更改结构,因此不能将其作为常量,因为这样就无法设置所需的字段。
  if (getaddrinfo (hostNameOrIPAddress,
          serviceOrPortNum,
          hints,
          resultOfGetAddrInfo) != 0)
    // Indicate some error.
    return 1;

  return 0;
return getaddrinfo (hostNameOrIPAddress,
              serviceOrPortNum,
              hints,
              resultOfGetAddrInfo) != 0;