2

我正在编写一个应用程序,我不得不做一些指针算术。然而,这个应用程序将在不同的架构上运行!我不确定这是否会有问题,但在阅读了这篇文章后,我认为我必须改变它。

这是我不太喜欢的原始代码:

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];
}

我想现在,编译器能说多少就跳转了!对?对数组的操作是否[]被视为指针算术?它是否解决了便携性问题?

4

3 回答 3

10

p + i和是指针和整数类型的值&p[i]时的同义词。这么多,你甚至可以写,它仍然有效(就像你可以写一样)。pi&i[p]i + p

您链接的示例中的可移植性问题来自sizeof(int)不同平台。您的代码很好,假设m_iHeaderLengthu_char您要跳过的 s 数量。

于 2012-11-14T08:41:07.157 回答
1

在您的代码中,您将 m_pLayerHeader 推进 m_iHeaderLength u_chars。只要写入您指向的数据的任何内容都具有相同的 u_char 大小,并且 i_HeaderLength 是您安全的标题区域中的 u_char 数。

但是如果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 位机器上,您具有相同的 Header 定义,并尝试读取信息。

port->read(packetBuffer, sizeof(Frame));

您已经遇到了麻烦,因为您尝试读取的数据量是发件人写入的数据量的两倍。在 16 位机器上进行读取的 int 大小为 2,而 header 的大小为 4。但是发送机器上的报头大小是 8,每个 4 字节的两个整数。

现在你试图推进你的指针

m_iHeaderLength = sizeof(Header);
...
packetBuffer += m_iHeaderLength;

packetBuffer仍将指向从始发者发送的帧中的标头中的数据。

于 2012-11-14T08:30:00.880 回答
0

如果存在可移植性问题,那么不,那不会解决它。m_pLayerHeader + m_iHeaderLength并且&m_pLayerHeader[m_iHeaderLength]是完全等价的(在这种情况下)。

于 2012-11-14T08:36:15.333 回答