user369823
user369823

Reputation: 361

memcpy vs strcat

Seems to be a basic question but I would rather ask this to clear up than spend many more days on this.I am trying to copy data in a buffer which I receive(recv call) which will be then pushed to a file. I want to use memcpy to continuously append/add data to the buffer until the size of buffer is not enough to hold more data where I than use the realloc. The code is as below.

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);
}

Problem: Whan ever I fputs the data into the file later on. Only the first data recv/added to buffer is gets into the file. Also when I print the value of vlBufferCopy(which points to first location of data returned by malloc or realloc) I get the same result. If I decrease the size by 1, I see entire data in the file, but it somehow misses the new line character and hence the data is not inserted in the proper format in the file. I know it is because of trailing '\0' but some how reducing the size by 1

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

misses the new line character. fputs while putting the data removes the trailing null character Please let me know what I am missing here to check or in the logic (Note: I tried using strcat:

strcat(vlBuffer,vl_data+PAD_SIZE);

but I wanted to use memcpy as it is faster and also it can be used for any kind of buffer and not only character pointer

Thanks

Upvotes: 4

Views: 5592

Answers (2)

arhuaco
arhuaco

Reputation: 1755

You need to write to the file in a binary-safe way. Check how to use fwrite instead of fputs. fwrite will copy all the buffer, even if there's a zero in the middle of it.

const char *mybuff= "Test1\0Test2";
const int mybuff_len = 11;
size_t copied = fwrite(mybuff, mybuff_len, 1, output_file);

Upvotes: 1

ugoren
ugoren

Reputation: 16441

strcat and memcpy are very different functions.
I suggest you read the documentation of each.

Mainly, there are two differences:
1. memcpy copies data where you tell it to. strcat finds the end of the string, and copies there.
2. memcpy copies the number of bytes you request. strcat copies until the terminating null.

If you're dealing with packets of arbitrary contents, you have no use for strcat, or other string functions.

Upvotes: 2

Related Questions