Browsing trumps searching

I was doing some maintenance work (bug fixing) on some code that was using the strncopy(src,dst,n)function to limit the number of bytes that were being copied.  Even though I’ve used this function hundreds of times, I never remember the exact details of what happens  with respect to the length and the terminating null character is it included as part of the length or isn’t it (it isn’t).   As a result I end up taking a trip into our QNX documentation and the C library reference to double check the behaviour.   Here is how the reading went this time for me:

 copy no more than n bytes over from dst to src. … yeah yeah …

then whammo the next line from the docs jumped right out at me:

If the string pointed to by src is shorter than n characters, null characters are appended to the copy in the array pointed to by dst, until n characters in all have been written.

Wow! So strncpy() is always padding out the full size of the buffer with null characters. I don’t know why this hadn’t struck me before, but this time I was looking at some code that was working with a large maximum buffer (4K) but was most often dealing with strings that were only 10 or 20 characters long.  Since this was being done repeatedly, it seemed like a code change was going to be in order, something along the lines of (using the same src,dst and n):

int len = strlen(src) + 1;  

if(len > n) { 
   len = n - 1; 
   dst[len] = ''; 

memcpy(dst, src, len);

This was kind of a drag since it was more code to write, but it was going to be a bit more efficient since we weren’t going to iterate over all 4K of the buffer padding it in with bytes we didn’t need … although we were passing twice through the string. Wanting to double check the order of the src and dst arguments for memcpy I headed back to the docs. I use the HTML index instead of the search so I jumped to the ‘M’ functions. Looking through the list I came across a library function I had never heard of before … memccpy so I thought I’d take a quick read of it:

Copy bytes between buffers until a given byte is found

Cool! That is exactly what I was looking for. The call does an efficient one pass iteration copying only the data bytes until it hit the matching character or it runs out of space to copy to.  I still needed to deal with ensuring the destination buffer was going to be null terminated (as with strncpy() ) but at least now I wasn’t spending any time filling in extra bytes as padding:

if(memcchr(dst, src, '', n) == NULL) { 
dst[n-1] = ''; 

So, now I get the security of a bounded string buffer copy and efficiency to boot and I picked up a new standard C API for my toolbox … all because I like to browse the API instead of using the indexed search!  Of course, perhaps at some point this will get even more straightforward if the strlcpy() function becomes part of POSIX/ANSI C standard.


1 comment so far

  1. Mario on

    Scenario like that are why I enjoy C++ so much these days.

    I have always been reluctant to use STL, thinking it was going to slow down program too much or bloat the code. Code is bigger yet but suprisingly not slower in fact in many cases it’s much faster. STL sort() min() max() are good example. It also much easier to write safer code.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: