指针算术和可移植性

时间:2012-11-14 08:26:54

标签: c++ pointers embedded pointer-arithmetic

我正在写一个应用程序,我不得不做一些指针算术。但是这个应用程序将在不同的架构上运行!我不确定这是否有问题,但在阅读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];
}

我想现在,编译器可以说多少跳!对?数组上的操作[]是否被视为指针算术?它是否解决了可移植性问题?

3 个答案:

答案 0 :(得分:10)

p + i是指针而&p[i]是整数类型的值时,

pi是同义词。甚至你甚至可以写&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]完全等效(在这种情况下)。