2012-02-22 4 views
0

При получении входящего msessage я получаю правильный результат, когда моя структура пакета имеет массив фиксированного размера в нем, как этотRecv пакеты с членами указателей

typedef struct inPacket{ 
    int cmd; 
    int seqNo; 
    int numbers[100]; 
} inPacket; 

потом называют Recv как так

char buf[1024]; 
recv(m_socket, buf, sizeof(buf)); 

и бросить массив символов с типом пакета

inPacket* p = (inPacket*)buf; 

Это прекрасно работает, у меня есть полный набор целых чисел в поле «числа» после кастинга. Я не могу думать, почему ниже не работает, при переходе в адресе, по которому я хочу сохранить номер

void func(int* out) 
{ 
    inPacket inpacket; 
    inPacket.numbers = out; 
    recv(m_socket, (char*)&inpacket, sizeof(inPacket)); 
} 

массив «цифр» плохой указатель после вызова RECV.

Массив Передаваемый выделяется функцией вызова

int numbers[10]; 
func(numbers); 
+1

Th не может быть реальным кодом. 'inPacket.numbers = out' приведет к ошибке. – cnicutar

ответ

2

Что делает recv, он копирует данные из внутреннего буфера в тот, который вы поставляете. Таким образом, он перезаписывает содержимое вашей структуры. Вы также меняете элемент массива на какой-то другой указатель, который не имеет значения. И не только это, вы пытаетесь установить его в массив, который меньше, чем существующий массив, который может привести к recv, возможно, перезаписать память за пределами вашего нового массива.

Вам нужно сделать что-то вроде этого:

void func(int* out, int maxnum) 
{ 
    inPacket inpacket; 
    recv(m_socket, (char*)&inpacket, sizeof(inPacket)); 

    memcpy(out, inpacket.numbers, sizeof(int) * maxnum); 
} 

Затем вызывается функция, как это:

int numbers[10]; 
func(numbers, 10); 

Edit: Если динамический массив хотел, то вызов recv должны быть изменены вместе со структурой:

typedef struct inPacket{ 
    int cmd; 
    int seqNo; 
    int numbers[0]; 
} inPacket; 

void func(int* out, int maxnum) 
{ 
    size_t packetSize = sizeof(inPacket) + sizeof(int) * maxnum; 
    inPacket *inpacket = malloc(packetSize); 

    recv(m_socket, inpacket, packetSize); 

    memcpy(out, inpacket->numbers, sizeof(int) * maxnum); 

    free(inpacket); 
} 
+0

в этом случае мне все еще не нужен массив чисел с фиксированным размером в структуре пакета? –

+0

@BillWalton Обновлен мой ответ. –

+0

Когда функция выходит, я теперь получаю проверку проверки времени выполнения. Урон из-за переменной «inPacket» был поврежден. Можете ли вы объяснить цель массива нулевого размера? Я не совсем понимаю, как это должно работать –

0

Я предполагаю, что RECV принимает размер буфера, и пытается заполнить ее. Но размер указателя - это просто int, поэтому он, вероятно, просто прочитал несколько (4?) Байта и захлопнул их в буфере. Для сообщений сокета среднего размера обычно требуется использовать некоторую структуру, которая знает, сколько байтов получаемого сообщения будет иметь (например, добавление сообщения с int, которое является размером остальной части сообщения, а затем соответствующим образом распределяет буфер и снова вызовите recv с новым буфером)

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