我正在写一个应用程序,我不得不做一些指针算术。但是这个应用程序将在不同的架构上运行!我不确定这是否有问题,但在阅读this article之后,我认为我必须改变它。
这是我原来不太喜欢的代码:
class Frame{
/* ... */
protected:
const u_char* const m_pLayerHeader; // Where header of this layer starts
int m_iHeaderLength; // Length of the header of this layer
int m_iFrameLength; // Header + payloads length
};
/**
* Get the pointer to the payload of the current layer
* @return A pointer to the payload of the current layer
*/
const u_char* Frame::getPayload() const
{
// FIXME : Pointer arithmetic, portability!
return m_pLayerHeader + m_iHeaderLength;
}
非常糟糕不是它!将int
值添加到u_char
指针!但后来我改为:
const u_char* Frame::getPayload() const
{
return &m_pLayerHeader[m_iHeaderLength];
}
我想现在,编译器可以说多少跳!对?数组上的操作[]
是否被视为指针算术?它是否解决了可移植性问题?
答案 0 :(得分:10)
p + i
是指针而&p[i]
是整数类型的值时, p
和i
是同义词。甚至你甚至可以写&i[p]
并且它仍然有效(正如你可以写i + p
)。
您链接的示例中的可移植性问题来自不同平台的sizeof(int)
。您的代码很好,假设m_iHeaderLength
是您要跳过的u_char
的数量。
答案 1 :(得分:1)
在您的代码中,您通过m_iHeaderLength u_chars推进m_pLayerHeader。只要写入您指向的数据的大小与u_char的大小相同,并且i_HeaderLength是标题区域中的u_chars数,那么您就是安全的。
但是如果m_iHeaderLength
实际上是指字节而不是u_chars,那么如果m_iHeaderLength
应该使指针超过其他类型而不是char,则可能会出现问题。
假设您要将数据从16位系统发送到32位系统,您的标题区域定义如下
struct Header {
int something;
int somethingElse;
};
假设这只是struct Frame定义的总消息的一部分。
在32位计算机上,将数据写入16位计算机将读取的端口。
port->write(myPacket, sizeof(Frame));
在16位计算机上,您具有相同的标头定义,并尝试阅读信息。
port->read(packetBuffer, sizeof(Frame));
您已经遇到了麻烦,因为您试图读取发件人写入的数据量的两倍。执行读取的16位机器上的int大小为2,标头大小为4。但是发送机器上的标头大小是8,每个4字节有两个整数。
现在你试图推进你的指针
m_iHeaderLength = sizeof(Header);
...
packetBuffer += m_iHeaderLength;
packetBuffer
仍将指向发件人发送的帧中标题中的数据。
答案 2 :(得分:0)
如果存在可移植性问题,那么不,那不会解决它。 m_pLayerHeader + m_iHeaderLength
和&m_pLayerHeader[m_iHeaderLength]
完全等效(在这种情况下)。