在特定情况下,指针删除和铸造之间的关系不清楚
Unclear relationship between pointer dereferencing and casting in a specific scenario
我有以下CPP函数:
u_long stringIpV4ToBinary(const char * ipv4)
{
u_long * buff[1];
int ret = InetPton(AF_INET, ipv4, &buff);
if (ret == -1) return 1;
if (ret == 0) return 1; // more handling needs to be added
// return ntohl(*buff[0]); // crash, no warning
// return ntohl((*buff)[0]); // same meaning above (??) crash, no warning
// return ntohl(**buff); // crash, no warning
// return ntohl(*(buff[0])); // crash, no warning
// return ntohl(*(u_long*)buff[0]); // crash, no warning
// return ntohl((u_long)buff[0]); // works, but produces warnings:: 'type cast': truncation from 'u_long *' to 'u_long'
// return ntohl(*(u_long*)&buff); // works
// return ntohl(*(u_long*)&buff[0]); // works
// return ntohl(*(u_long*)buff[0]); // crash, no warning
// return ntohl(*(u_long*)buff); // works
}
我花了一些时间试图提取我需要传递给ntohl()
的buff值(因此您可以忽略前几行)。我正在玩*buff[0]
*buff
和其他人,因为我意识到我需要施放数组的第一个元素的值( &buff[0]
, buff
或 &buff
)。
问题:为什么我需要将检索到的值投放到(u_long*)
,然后授予指针?@ @ Runtime中持有buff[0]
中持有的值是u_long *
类型的A模棱两可或不清楚吗?我的期望是 ntohl(**buff)
-(buff是数组名称,它腐烂到指针中,并且由于数组是u_long pointers本身的),双重删除应该足够。
您的 buff
定义为 pointer 的数组(尺寸1) u_long
。因此,InetPton
将所得的IP地址直接存储在此指针变量中。然后,您会崩溃,因为此IP地址被解释为内存地址并重新引用。
buff
应定义为简单的u_long
,其地址传递给InetPton
:
u_long buff;
int ret = InetPton(AF_INET, ipv4, &buff);
然后您可以这样做:
return ntohl(buff);
在此改进,如果第一个参数的值为 AF_INET
:
INT WSAAPI InetPton( _In_ INT Family, _In_ PCTSTR pszAddrString, _Out_ PVOID pAddrBuf );
...
指定此参数时,
pszAddrString
参数必须 指向IPv4地址和pAddrBuf
的文本表示形式 参数返回指向IN_ADDR
结构的指针 IPv4地址。
因此,您应该在第三个参数中传递IN_ADDR
的地址:
IN_ADDR addr;
int ret = InetPton(AF_INET, ipv4, &addr);
...
return ntohl(addr.S_addr);
编辑:
扩展了为什么演员会有所作为,事实证明它没有。有所不同的是间接水平和您退出多少次。
传递给ntohl
的参数不需要铸造。
解析IPv4字符串地址时InetPton
只需要一个可以写4个字节的内存中的地址。
u_long addr; // 4 bytes on Windows
int ret = InetPton(AF_INET, ipv4, &addr);
if (ret == -1) return 1;
if (ret == 0) return 1; // more handling needs to be added
return ntohl(addr);
理想情况下,您将使用IN_ADDR
类型,但是如果您只关心Windows,则可以直接使用基于long
的类型。
在需要将数据存储在上述变量中时,将堆栈上的变量声明为指针(*
)是没有道理的,这是C101。
InetPton
的呼叫将32位IPv4地址写入buff
中的第一个u_long *
。
双重主管的所有变体都将该值对待,就像是指指针一样。不是,这就是为什么他们崩溃的原因。
工作的人只能执行单个解雇并将结果视为长时间,这就是它们工作的原因。(尽管我怀疑其中许多人实际上具有未指定或未定义的行为,因为您对该值是指针还是整数非常狂热。)
如果将buff
声明为IN_ADDR
,您的代码可能更简单且明显正确。
- this_thread::sleep_for和计时时钟之间的关系是否由C++11标准指定
- 我已经建立了递归关系,它找到了两个字符串之间最长的连续公共字符串,我怎么能跳过其中一个字符串中的一个字符
- 移动语义和深层/浅层复制之间有什么关系?
- #include < conio.h> 和 getch() 方法之间的关系是什么?
- 超市管理系统的类别之间应该是什么关系?
- 指针和程序性能之间有什么关系吗?
- node.h/node.cpp/nodelist.cpp之间的关系
- 运行线程和线程对象之间的关系
- 类型大小与其值范围之间的关系?
- 2个期货之间的依赖关系
- Qt:工作线程和 GUI 事件之间的关系
- 如何强制 qbs 产品与依赖关系之间的同步?
- 在头文件和 .cc 文件之间建立关系
- C 和Windows OS之间的关系
- 为什么赋值运算符和相等运算符之间没有 1:1 的关系?
- QComboBox 在 editTextChanged 和 currentIndexChanged 之间的关系
- 使用 .depends 指定 SUBDIRS 项目之间的依赖关系不起作用
- 各种初始化和构造之间的关系
- 变量之间的关系
- 有符号整数类型的最小值和最大值之间关系的C++标准保证是什么