Арифметика и переносимость указателя

Я пишу заявку, и мне нужно было сделать несколько арифметических указателей. Однако это приложение будет работать на другой архитектуре! Я не был уверен, если это будет проблематично, но после прочтения Эта статья, Я думал, что я должен изменить это.

Вот мой оригинальный код, который мне не очень понравился:

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

Я думаю, теперь компилятор может сказать, сколько прыгать! Правильно? Является ли операция [] на массиве рассматривается как указатель арифметики? Устраняет ли это проблему переносимости?

2

Решение

p + i а также &p[i] синонимы, когда p это указатель и i значение целочисленного типа. Так много, что вы даже можете написать &i[p] и это все еще действует (так же, как вы можете написать i + p).

Проблема переносимости в примере, на который вы ссылаетесь, исходила sizeof(int) варьируется на разных платформах. Ваш код просто отлично, если m_iHeaderLength это число u_charВы хотите пропустить.

10

Другие решения

В вашем коде вы продвигаете m_pLayerHeader на m_iHeaderLength u_chars. Пока все написанные данные имеют одинаковый размер для u_char, а i_HeaderLength — это число u_chars в области заголовка, которое вы в безопасности.

Но если m_iHeaderLength действительно ссылается на байты, а не на u_chars, тогда у вас могут возникнуть проблемы, если m_iHeaderLength Предполагается, что указатель опережает другие типы, кроме char.

Скажем, вы отправляете данные из 16-битной системы в 32-битную систему, область заголовка определяется следующим образом

struct Header {
int something;
int somethingElse;
};

Предположим, что это только часть общего сообщения, определенного структурой Frame.

На 32-битной машине вы записываете данные в порт, с которого 16-битная машина будет читать.

port->write(myPacket, sizeof(Frame));

На 16-битной машине у вас такое же определение заголовка, и вы пытаетесь прочитать информацию.

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

У вас уже есть проблемы, потому что вы пытались прочитать вдвое больше данных, которые написал отправитель. Размер int на 16-битной машине, выполняющей чтение, равен двум, а размер заголовка равен четырем. Но размер заголовка на отправляющем компьютере составлял восемь, по два дюйма по четыре байта каждый.

Теперь вы пытаетесь продвинуть указатель

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

packetBuffer будет по-прежнему указывать на данные, которые были в заголовке в кадре, отправленном отправителем.

1

Если есть проблема с переносимостью, то нет, это не решит проблему. m_pLayerHeader + m_iHeaderLength а также &m_pLayerHeader[m_iHeaderLength] полностью эквивалентны (в этом случае).

0
По вопросам рекламы [email protected]