2009-07-26 8 views
6

При приеме данных через сокет с помощью recv, я заметил, что, с:массив символов по сравнению с указателем полукокса

 
char buffer[4]; 
memset(buffer, 0, 4); 
recv(socket, buffer, 4, 0); 

Я получаю

mesgx

«mesg» - это то, что я отправил, с добавлением некоторых случайных символов.

Если я использую

 
char * method = (char *) malloc(4); 
memset(buffer, 0, 4); 
recv(socket, buffer, 4, 0); 

вместо этого, я получаю

MESG

Так что нет случайных вещей прилагается к моей строке. Я понял, что если я использую char [5], то он работает так же хорошо, но я действительно не понимаю, почему. Действительно ли malloc (4) выделяет 5 байтов, пятый - NUL?

ответ

16

Вызов malloc(4) действительно выделяет только четыре байта. Было просто совпадением, что следующий байт в памяти оказался NUL, который прервал вашу строку для вас.

В случае, когда в стеке было выделено char buffer[4], следующий байт оказался 'x', за которым следуют некоторые другие вещи, поэтому ваша строка продолжалась до тех пор, пока не найдет следующий байт NUL.

Функции сокетов относятся только к байтам и не обрабатывают байты как строки с завершающим NUL или чем-то дополнительным. Вы получаете именно то, о чем просите.

6

Вам нужно 5 символов, чтобы они были надлежащим образом завершены NULL. Конечный NULL считается как один, поэтому, если нам нужны N символов, выделите N + 1. Или, наоборот, для распределения N у вас есть N-1, доступный для вашего контента.

+0

Я так много думал, но почему он работает с malloc? – fresskoma

2

Возможно, вы получили не более 4 char s, поскольку вы только указали recv максимум 4 байта, которые будут помещены в ваш буфер. Вы должны проверить возвращаемое значение recv, чтобы узнать, сколько байтов было фактически возвращено.

Я подозреваю, что проблема заключается в том, что вы не заботитесь только о выходе 4 char s из любой процедуры, генерирующей вывод. Один из способов отображения начального содержимого буфера char с нулевым нулем - это.

printf("%.4s\n", buffer); 

Полный фрагмент recv вызова может быть:

#define MAX_BUF_LEN (512) 
char buffer[MAX_BUF_LEN]; 
ssize_t count = recv(socket, buffer, MAX_BUF_LEN, 0); 

if (count > 0) 
    printf("%.*s\n", count, buffer); 
3

Я подозреваю, что разница является совпадением. Когда вы используете буфер в виде строки, например, в printf(), он будет считан за пределом до тех пор, пока не будет найден «\ 0».

В обоих случаях следует использовать буфер [5] или malloc (5). Функция memset() не должна быть необходимой, лучше поместите буфер [4] = '\ 0' после recv().