【问题标题】:How to access a member of a struct which is passed into a function as pointer to pointer parameter?如何访问作为指针参数指针传递给函数的结构成员?
【发布时间】:2021-06-04 20:58:10
【问题描述】:

我有一个结构:

typedef struct addrinfo
{
    int ai_flags;
    int ai_family;
    int ai_socktype;
    int ai_protocol;
    size_t ai_addrlen;
    char *ai_canonname;
    struct sockaddr *ai_addr;
    struct addrinfo *ai_next;
} ADDRINFOA, *PADDRINFOA;

我定义了一个函数,它接受指向 struct addrinfo 类型指针的指针并通过“指针引用”返回值

void getAddress(addrinfo **addr){
     addr->ai_addr->sa_data = "0.0.0.0";   //sa_data is a member of ai_addr
}

我使用以下代码调用了函数 getAddress:

addrinfo *IPAddr = new addrinfo();
IPAddr->ai_addr = new sockaddr(); 
getAddress(&IPAddr);

我收到一个错误:

error: request for member 'ai_addr' in '* IPAddr ', which is of pointer type 'addrinfo*' (maybe you meant to use '->' ?)
*IPAddr ->ai_addr->sa_data[14] = {"10.10.10.10"};

【问题讨论】:

  • 当你只想从中读取指针时,为什么要将指针作为参数传递?
  • 这只是一个使用指针传递引用的练习函数。这种情况更棘手,因为我想访问父结构的成员结构并且不能使用类似:*pointer_to_pointer_parameter = &(a_value)。我希望任何调用 getAddress 都会在函数 getAddress 关闭后更改 pointer_to_pointer_parameter 的值。
  • 指向指针的指针通常意味着函数将分配结构(在堆上),初始化它的值并更新参数以传回新分配结构的地址;即工厂函数。
  • void getAddress( **addr) 缺少 addr 的类型信息。
  • 同样在 C++ 中,实际上通过引用传递更为惯用,例如:void getAddress( addrinfo*& addr) 而不是传递指针到指针(这是在 C 中实现的方式)

标签: c++ pointers pass-by-reference


【解决方案1】:

addr->ai_addr 等价于 (*addr).ai_addr(*addr) 返回指向 addrinfo 的指针。这就是错误消息告诉您的内容。您不能从指针访问成员。您必须取消引用 addr 两次,例如(*addr)->ai_addr(**addr).ai_addr

【讨论】:

  • 谢谢!它修复了。另外,你能解释一下为什么函数getAddress里面的* addr->ai_addr->sa_data不起作用,但是(*addr)起作用。
  • @MinhPham 那叫operator precedence-> 的优先级高于 **a->b 相当于 *(a->b) 但你需要 (*a)->b
【解决方案2】:

您需要取消引用addr (*addr) 以获取addrinfo*,并且您不能将C 字符串直接分配给char[] sa_data,您需要将C 字符串复制到地点。

例子:

#include <algorithm>
#include <iterator>

void getAddress(addrinfo **addr){
    static const char zeroes[] = "0.0.0.0";
    std::copy_n(zeroes, std::size(zeroes), (*addr)->ai_addr->sa_data);
}

注意:根据C++ Operator Precedence *(取消引用)的优先级低于-&gt;(成员访问),因此我们需要将(*addr) 括在括号中以便取消引用(*addr)-&gt;ai_addr-&gt;sa_data 中的addr

【讨论】:

  • 谢谢!您修复了 1 cmets 中的 2 个错误。另外,您能否解释一下为什么 *addr 不起作用但 (*addr) 起作用?
  • @MinhPham 不客气。我在答案中添加了解释。
猜你喜欢
  • 1970-01-01
  • 2017-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多