Почему динамически размещенный массив не обновляется при поступлении новых данных? - PullRequest
0 голосов
/ 01 февраля 2020

Я пытаюсь получить сообщение от сервера сокетов, который отправляет большой файл размером около 7 МБ. Таким образом, в следующем коде я пытаюсь объединить все данные в один массив s из buffer. Но, пробуя следующее, я вижу, что длина s не меняется вообще, хотя общее количество полученных байтов продолжает увеличиваться.

char buffer[300];
char* s = calloc(1, sizeof(char));
size_t n = 1;
while ((b_recv = recv(socket_fd,
                              buffer,
                              sizeof(buffer), 0)) > 0) {


   char *temp = realloc(s, b_recv + n);
   s = temp;
   memcpy(s + n -1, buffer, b_recv);
   n += b_recv;
   s[n-1] = '\0';
   printf("%s -- %zu",s, strlen(s));

}

free(s);

Разве это не правильный способ обновления данных приема разных размеров? Кроме того, когда я пытаюсь напечатать s, он дает несколько символов случайного знака вопроса. Какую ошибку я совершаю?

1 Ответ

1 голос
/ 01 февраля 2020

Почему динамически размещаемый массив не обновляется при поступлении новых данных?

Вы не представили никаких оснований полагать, что поведение таково, как вопрос характеризует его. Вы получаете двоичные данные и сохраняете их в памяти, что нормально, но вы не можете ожидать ощутимых результатов от обработки таких данных, как если бы это была строка C. Даже когда вы заменяете последний байт символом конца строки.

Двоичные данные могут и обычно содержат байты со значением 0. C строки используют такие байты как терминаторы, обозначающие конец данных строки, поэтому например, strlen будет измерять только количество байтов перед первым нулевым байтом, независимо от того, сколько дополнительных байтов было сохранено после него. Более того, даже если вы вообще не получаете нулевых байтов, ваш конкретный код вставляет их, что приводит к засорению некоторых полученных реальных байтов.

Вы можете попытаться распечатать такие данные на консоли как если бы это был текст, но если на самом деле он не состоит из текста, закодированного в соответствии с кодировкой символов во время выполнения, то нет никаких оснований ожидать, что в результате на экране отобразится полезная информация. Вместо этого изучите его в памяти с помощью отладчика или запишите необработанные байты в файл и изучите результат с помощью шестнадцатеричного редактора или запишите их (все еще необработанные) через фильтр, который преобразуется в шестнадцатеричное или другое текстовое представление, или подобное. И у вас есть столько байтов для проверки, сколько вы скопировали в выделенное пространство. Вы уже отслеживаете это, поэтому вам не нужно strlen(), чтобы сказать вам, сколько это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...