错误:在只读对象中分配成员ai_family

时间:2014-07-12 11:20:04

标签: c linux sockets gcc

#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,我会遇到分段错误。

2 个答案:

答案 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;

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