2012-02-13 3 views
6

Рассмотрим меня STRUCT как следующее:Является ли адрес структуры таким же, как адрес его первого члена?

struct Bitmask 
{ 
    unsigned char payload_length: 7; 
    unsigned char mask: 1; 
    unsigned char opcode: 4; 
    unsigned char rsv3: 1; 
    unsigned char rsv2: 1; 
    unsigned char rsv1: 1; 
    unsigned char fin: 1; 
}; 

const char* payload = "Hello"; 
const size_t payload_length = strlen(payload); 

Bitmask* header = new Bitmask(); 
header->fin =1; 
header->rsv1 = 0; 
header->rsv2 = 0; 
header->rsv3 = 0; 
header->opcode = 1; 
header->mask = 0; 
header->payload_length = payload_length; 

iovec iov[2]; 
iov[0].iov_base = (char*)header; 
iov[0].iov_len = sizeof (header); 
iov[1].iov_base = (char *)payload; 
iov[1].iov_len = strlen(payload); 

ACE_DEBUG ((LM_DEBUG, 
      ACE_TEXT ("iov[0].length = %d\niov[1].length = %d\n"), 
      iov[0].iov_len, 
      iov[1].iov_len)); 

size_t bytes_xfered; 
client_stream_.sendv_n (iov, 2, 0, &bytes_xfered); 

cout << "Transfered " << bytes_xfered << " byte(s)" << std::endl; 

Я инициализацией его с соответствующими значениями. Наконец, я хочу преобразовать структуру в char *, чтобы добавить свою полезную нагрузку (которая является сообщением char *) и отправить ее по подключению к сети.

ответ

14

Адрес структуры такой же, как адрес ее первого члена?

Да, на самом деле это предусмотрено стандартами C и C++. Из стандарта С:

6.7.2.1-13. Указатель на структурный объект, соответствующим образом преобразованный, указывает на его исходный элемент

Размер вашего struct должен составлять два байта. Вам не следует преобразовывать указатель на него в char*: вместо этого вы должны использовать memcpy, чтобы скопировать Bitmask в буфер, который вы отправляете по сети.

EDIT Поскольку вы используете Разброс-собирать I/O с iovec, вам не нужно бросить Bitmask ни к чему: iov_base является void*, так что вы можете просто установить iov[0].iov_base = header;

Примечание: Это работает только до тех пор, поскольку ваш struct не содержит виртуальных функций, базовых классов и т. д. (спасибо, Тимо).

EDIT2

Для того, чтобы получить {0x81, 0x05} в вашем struct, вы должны изменить порядок элементов структуры следующим образом:

struct Bitmask { 
    unsigned char opcode: 4; 
    unsigned char rsv3: 1; 
    unsigned char rsv2: 1; 
    unsigned char rsv1: 1; 
    unsigned char fin: 1; 
    unsigned char payload_length: 7; 
    unsigned char mask: 1; 
} 
+7

В C++ это справедливо только для структур POD. – Timo

+0

Нужно ли копировать элемент Bitmask членом или следующим образом: char header_ [2]; memcpy (header_, bitmask, 2); –

+0

@DarshanPuranik Я не понимал, что вы используете разбор-сборку ввода-вывода. См. Мое редактирование. – dasblinkenlight

1

Да и нет.

В общем, это правда (как объясняет dasblinkenlight), но он специально не подходит для битполей. Per C++ 11 9.6/3 «нет указателей на битовые поля», поэтому у них также нет адресов. И, очевидно, «Указатель на объект структуры, , подходящим образом преобразованный, указывает на его начальный член« ломается, если нет «подходящего преобразования».

1

Адрес структуры совпадает с адресом ее первого элемента при условии, что используется соответствующий литой. Учитывая нижеследующее объявление структуры my_struct, если элемент имеет тип struct

my_struct, then (char *) item == & item.wp_cval.

структура my_struct {

char wp_cval; 
    short wp_font; 
    short wp_psize; 

} ар [ARSIZE];

Смежные вопросы