2012-05-18 3 views
0
#include <stdint.h> 
#include <stdio.h> 
#include <stdlib.h> 

char* createMSG(uint8_t i,uint32_t port); 

int strlen(char* tmp); 
uint32_t user_port = 5000; 

int main(int argc, char** argv) { 
    char *msg; 
    uint8_t i; 
    i = 1; 
    msg = createMSG(i,user_port); 
    printf("Port: %d",*(msg+2)); 
} 

char* createMSG(uint8_t i,uint32_t port) { 
    char *buff; 
    buff = (char*) malloc(6); 
    uint8_t id; 
    id = 2; 
    memcpy(buff, &id, sizeof(uint8_t)); 
    memcpy(buff+1, &i, sizeof(uint8_t)); 
    memcpy(buff+2, &port, sizeof(uint32_t)); 
    return buff; 
} 

Выход: «Порт: -120». Кажется, что есть переполнение. Но uint32_t должен быть достаточно большим для 5000. При использовании 22 вместо 5000 все в порядке.переполнение при использовании uint32_t

Почему?

+2

Также '% d' не является правильным форматом для' uint32_t'. Сначала это будет формат значащего значения, а не без знака. Тогда вы обычно не знаете, соответствует ли 'unsigned' 32-разрядному типу. Правильный макрос для формата - 'PRIu32' что-то вроде' 'Port:%" PRIu32 "\ n" '(да это уродливо). Также не забывайте '\ n' в конце' printf', чтобы убедиться, что вы видите результат. –

+0

Привет, я никогда не слышал о PRIu32. С этого момента я буду PRIu32, чтобы предотвратить неожиданное поведение. До настоящего времени% d всегда выполнял свою работу. При отправке msg с sendto() я снова получаю неправильное значение для * (msg + 2), даже если я использую '(uint32_t *)'. – user1324258

ответ

2

Эта линия

printf("Port: %d",*(msg+2)); 

печатает 'символ' значение в (МВП + 2) адрес, а не uint32_t!

Использование

uint32_t PortFromProc = *(uint32_t*)(msg+2); 
printf("Port: %d", PortFromProc); 

Чтобы "исправить" номера порта из recvfrom() функция следует использовать функцию ntohl().

+0

Привет, это работает. Но при отправке msg с sendto() (UDP) и его получении с recvfrom uint32_t PortFromProc = * (uint32_t *) (msg + 2); снова имеет неправильное значение. – user1324258

+1

Номера портов в recvfrom() в формате big-endian (старший байт идет первым). Используйте функции ntohs/ntohl для значения, полученного из recvfrom(). –

+0

Dp вы имеете в виду sth как этот 'uint32_t PortFromProc = htonl (* (uint32_t *) (msg + 2));'? – user1324258

4

Потому что *(msg+2) имеет тип char. Если вы действительно хотите сделать это, вы должны сделать

printf("Port: %d",*(uint32_t*)(msg+2)); 

Как отметил @R .., MSG + 2 почти наверняка не соответствует требованиям, выравнивание по правому краю для типа uint32_t. Если код работает, это случайный случай, а не переносимый.

+0

А теперь это работает. Спасибо! – user1324258

+1

Это недопустимый код. 'msg + 2' почти наверняка не соответствует требованиям правильного выравнивания для типа' uint32_t'; если код работает, это случайный случай, а не переносимый. –

+0

@R ..: Это хороший момент, я добавлю его к ответу. –

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