memcpy против strcat - PullRequest
       1

memcpy против strcat

4 голосов
/ 11 марта 2012

Кажется, что это основной вопрос, но я бы лучше попросил это прояснить, чем тратить на это больше дней. Я пытаюсь скопировать данные в буфер, который я получаю (вызов recv), который затем будет помещен в файл. , Я хочу использовать memcpy для непрерывного добавления / добавления данных в буфер до тех пор, пока размер буфера не станет достаточным для хранения большего объема данных, чем в случае использования realloc. Код, как показано ниже.

int vl_packetSize = PAD_SIZE + (int)p_size - 1; // PAD_SIZE is the size of char array sent 
                        //p_size is the size of data to be recv. Same data size is used by send 
int p_currentSize = MAX_PROTO_BUFFER_SIZE;
int vl_newPacketSize = p_currentSize;

char *vl_data = (char *)malloc(vl_packetSize);
memset((char *)vl_data,'\0',vl_packetSize);


/* Allocate memory to the buffer */
vlBuffer = (char *)malloc(p_currentSize);
memset((char *)vlBuffer,'\0',p_currentSize);
char *vlBufferCopy = vlBuffer;

if(vlBuffer==NULL)
    return ERR_NO_MEM;

/* The sender first sends a padding data of size PAD_SIZE followed by actual data. I want to ignore the pad hence do vl_data+PAD_SIZE on memcpy */
if((p_currentSize - vl_llLen) < (vl_packetSize-PAD_SIZE)){
  vl_newPacketSize +=vl_newPacketSize;
  char *vlTempBuffer = (char *)realloc(vlBufferCopy,(size_t)vl_newPacketSize);
  if(vlTempBuffer == NULL){
     if(debug > 1)
    fprintf(stdout,"Realloc failed:%s...Control Thread\n\n",fn_strerror_r(errno,err_buff));
    free((void *)vlBufferCopy);
    free((void *)vl_data);
    return ERR_NO_MEM;  
      }
    vlBufferCopy = vlTempBuffer;
    vl_bytesIns = vl_llLen;
    vl_llLen = 0;
    vlBuffer = vlBufferCopy+vl_bytesIns;
    fprintf(stdout,"Buffer val after realloc:%s\n\n",vlBufferCopy);
}

memcpy(vlBuffer,vl_data+PAD_SIZE,vl_packetSize-PAD_SIZE);

/*
fprintf(stdout,"Buffer val before increment:%s\n\n",vlBuffer);
fprintf(stdout,"vl_data length:%d\n\n",strlen(vl_data+PAD_SIZE));
fprintf(stdout,"vlBuffer length:%d\n\n",strlen(vlBuffer));
*/

vlBuffer+=(vl_packetSize-PAD_SIZE);
vl_llLen += (vl_packetSize-PAD_SIZE);
vl_ifNotFlush = 1;
//fprintf(stdout,"Buffer val just before realloc:%s\n\n",vlBufferCopy);
}

Проблема: когда я добавляю данные в файл позже. Только первые данные, добавленные в буфер, попадают в файл. Также, когда я печатаю значение vlBufferCopy (которое указывает на первое местоположение данных, возвращаемых malloc или realloc), я получаю тот же результат. Если я уменьшаю размер на 1, я вижу все данные в файле, но он как-то пропускает символ новой строки и, следовательно, данные не вставлен в правильном формате в файле. Я знаю, что это из-за конечного '\ 0', но кое-как уменьшить размер на 1

(vlBuffer+=(vl_packetSize-PAD_SIZE-1);)

пропускает символ новой строки. fputs при вводе данных удаляет завершающий нулевой символ Пожалуйста, дайте мне знать, что мне не хватает здесь, чтобы проверить или в логике (Примечание: я пытался использовать strcat:

strcat(vlBuffer,vl_data+PAD_SIZE);

но я хотел использовать memcpy, так как он быстрее, а также его можно использовать для любого буфера, а не только для символьного указателя

Спасибо

Ответы [ 2 ]

2 голосов
/ 11 марта 2012

strcat и memcpy - это очень разные функции.
Я предлагаю вам прочитать документацию каждого.

В основном, есть два отличия:
1. memcpy копирует данные туда, куда вы их указываете. strcat находит конец строки и копирует туда.
2. memcpy копирует количество байтов, которые вы запрашиваете. strcat копирует до завершающего нуля.

Если вы имеете дело с пакетами произвольного содержимого, вы не можете использовать strcat или другие строковые функции.

1 голос
/ 12 марта 2012

Вам необходимо записать в файл безопасным для двоичного кода способом.Проверьте, как использовать fwrite вместо fputs.fwrite скопирует весь буфер, даже если в его середине есть ноль.

const char *mybuff= "Test1\0Test2";
const int mybuff_len = 11;
size_t copied = fwrite(mybuff, mybuff_len, 1, output_file);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...