Добавление к динамически выделяемому массиву

#c

#c

Вопрос:

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

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

Я добавляю только применимые строки кода.

 int buffersize=10000;
void *BuffPtr = (void *)calloc(1,buffersize * sizeof(char));
 

Затем у меня recv есть из UDP (я пробовал получать в массив символов и динамически выделяемый массив — оба работают нормально)

 // Setup socket......

void *PktBuff = (void *)calloc(1,1000 * sizeof(char));

// Loop and receive many packets......

rcvd_bytes=recv(recv_socket, PktBuff, 1000, 0);
 

На данный момент я могу написать содержимое, PktBuff и это работает нормально. Но я хочу объединить несколько полученных пакетов в моем динамически распределяемом массиве ( BuffPtr определенном выше).

Я пробовал strcat, но я просто удаляю мусор, если пытаюсь записать первый полученный пакет, не получая другого пакета.

 strcat(BuffPtr, PktBuff);
 

Что я делаю не так??

Заранее благодарю.

Комментарии:

1. strcat использует » в качестве завершителя строки. Попробуйте добавить его после strcat .

2. Вы выполняете calloc вызов неправильно: первый аргумент — это количество выделяемых элементов ( buffersize в первом фрагменте кода), а второй аргумент — размер каждого элемента. Так и должно быть calloc(buffersize, sizeof(char)) .

3. @BigMike ошибка нет … это предполагает, что BuffPtr состоит только из байтов, отличных от 0.

Ответ №1:

Ваши данные, похоже, не являются строками с завершением 0, которые вы можете использовать memmove вместо этого.

Комментарии:

1. Возможно, он мог бы работать с чтением в 999 байт в PktBuff? Поскольку calloc ноль инициализирует память.

2. Или выделение 1001 байта. То есть, если мы предположим, что в данных нет нулей.

3. Майкл, я попробовал memove, это работает для первого экземпляра, затем я получаю мусор для второго и последующих пакетов.

4. Просто будьте осторожны с тем, что и куда вы перемещаете, и убедитесь, что у вас достаточно места для перемещения вещей.

5. Хорошо, у меня достаточно места, но все та же проблема — мой цикл recv объединяется в первый раз, но во второй раз в конец моего динамически выделяемого массива добавляется только одна строка «мусора» — или так кажется — буфер recv содержит правильную информацию, но memmoveили memcpy просто добавляет мусор. Какие-нибудь идеи, пожалуйста?

Ответ №2:

Несколько моментов и наблюдений:

  1. Не приводите возвращаемое значение malloc() в C.
  2. Выражение sizeof (char) представляет собой многословный способ записи 1 , умножение на него редко бывает информативным.
  3. Убедитесь, что все ваши данные завершаются 0 (строки), иначе вы не сможете использовать строковые функции, поскольку это то, что им требуется.
  4. Вероятно, вам следует просто использовать дополнительный size_t счетчик для отслеживания количества байтов в BuffPtr и использовать его и memcpy() для добавления.

Комментарии:

1. Спасибо, у меня есть счетчик общего количества байтов в BuffPtr, и, следуя совету Майкла, я использовал memove, что немного улучшает ситуацию. Должно быть, мне не хватает чего-то вроде завершающей строки в пакете?? Будет проверяться.

Ответ №3:

Хорошо, ряд проблем в вашем коде strcat НЕ является правильным способом добавления двоичных данных. Вот полуустойчивая реализация. Я НЕ проверял его на наличие синтаксических ошибок, просто ввел его, пожалуйста, изучите его в качестве примера и адаптируйте к своему коду.

 /* total number of bytes you are willing to receive in single a single receive */ 
#define MAX_RECV_BUFFER 1000

/* total number of bytes you are willing to store in memory */
#define MAXBYTES MAX_RECV_BUFFER*1000

int append_bytes() {
    char rcvbuf[MAX_RECV_BUFFER]; /* buffer where things are received */
    void *buf = NULL; /* buffer where bytes are collected */
    size_t rcvlen; /* length of data received */
    size_t buflen = 0; /* total bytes */

    while(1) {
         void *p;
         rcvlen = recv(recv_socket, rcvbuf, MAX_RECV_BUFFER, 0);
         if ( rcvlen < 0 ) { manage_error(); }
         if ( rcvlen == 0 ) 
                 break;
         if ( buflen   rcvlen > MAXBYTES) 
                 break;
         p = realloc(buf, buflen recvlen);
         if ( !p ) { manage_memory_error(); }
         buf = p; /* we have enough space */
         memcpy(buf buflen, rcvbuf, recvlen); /* append new content to end of buffer */
         buflen =recvlen; /* add length to buflen */
    }      
}
 

Комментарии:

1. Спасибо, но компилятору не нравится memcpy. Я объявил вещи точно так же, как вы (удалив мой предыдущий calloc), и получаю ошибку компилятора, ссылающуюся на аргумент buf buflen в memcpy: выражение должно быть указателем на полный тип объекта??????