Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastest way to get the null char in a copied string in C

I need to get the pointer to the terminating null char of a string.

Currently I'm using this simple way: MyString + strlen(MyString) which is probably quite good out of context.

However I'm uncomfortable with this solution, as I have to do that after a string copy:

char MyString[32];
char* EndOfString;
strcpy(MyString, "Foo");
EndOfString = MyString + strlen(MyString);

So I'm looping twice around the string, the first time in strcpy and the second time in strlen.

I would like to avoid this overhead with a custom function that returns the number of copied characters:

size_t strcpylen(char *strDestination, const char *strSource)
{
    size_t len = 0;
    while( *strDestination++ = *strSource++ )
        len++;
    return len;
}

EndOfString = MyString + strcpylen(MyString, "Foobar");

However, I fear that my implementation may be slower than the compiler provided CRT function (that may use some assembly optimization or other trick instead of a simple char-by-char loop). Or maybe I'm not aware of some standard builtin function that already does that?


I've done some poor's man benchmarking, iterating 0x1FFFFFFF times three algorithms (strcpy+strlen, my version of strcpylen, and the version of user434507). The result are:

1) strcpy+strlen is the winner with just 967 milliseconds;

2) my version takes much more: 57 seconds!

3) the edited version takes 53 seconds.

So using two CRT functions instead of a custom "optimized" version in my environment is more than 50 times faster!

like image 886
lornova Avatar asked Dec 21 '22 21:12

lornova


2 Answers

Hacker's Delight has a nice section on finding the first null byte in a C string (see chapter 6 section 1). I found (parts of) it in Google Books, and the code seems to be here. I always go back to this book. Hope it's helpful.

like image 29
Dervin Thunk Avatar answered Dec 24 '22 11:12

Dervin Thunk


size_t strcpylen(char *strDestination, const char *strSource)
{
    char* dest = strDestination;
    while( *dest++ = *strSource++ );
    return dest - strDestination;
}

This is almost exactly what the CRT version of strcpy does, except that the CRT version will also do some checking e.g. to make sure that both arguments are non-null.

Edit: I'm looking at the CRT source for VC++ 2005. pmg is correct, there's no checking. There are two versions of strcpy. One is written in assembly, the other in C. Here's the C version:

char * __cdecl strcpy(char * dst, const char * src)
{
        char * cp = dst;

        while( *cp++ = *src++ )
                ;               /* Copy src over dst */

        return( dst );
}
like image 142
Eugene Smith Avatar answered Dec 24 '22 11:12

Eugene Smith