-
Playing around strlen :)
Code:
#include <stdio.h>
#include <string.h>
/*
The std's strlen algorithm:
From: Programming with lcc-win32 by Jacob Navia and Q Software Solutions GmbH
int strlen(char *str)
{
char *p = str;
while(*p != 0)
p++;
return p - str;
}
It will crash in both..
char *test;
printf("%d", strlen(test));
..and..
char *test = NULL;
printf("%d", strlen(test));
*/
//This is my modified std's strlen:
int strlen_mod(char *str)
{
//Avoiding crashes by initializing string to NULL
if(str == NULL) //a very simple fix
return 0;
char *p = str;
while(*p != 0)
p++;
return p - str;
}
//They said passing by reference gives better performance:
int strlen_byref(char **str)
{
if(*str == NULL)
return 0;
char *p = *str;
while(*p != 0)
p++;
return p - *str;
}
//But, let's try something simple :) :
int strlen_simple(char **str)
{
if(*str == NULL)
return 0;
int len = 0;
while((*str)[len] != 0)
len++;
return len;
}
int main()
{
char *str = "abcde";
printf("%s\n\n", str);
printf("strlen : %d\n", strlen(str));
printf("strlen_mod : %d\n", strlen_mod(str));
printf("strlen_byref : %d\n", strlen_byref(&str));
printf("strlen_simple: %d\n", strlen_simple(&str));
return 0;
}
Comments are welcome :)
-
Well I think strlen was written that way because it expects the string to have something and not simply just be the declared variable passed in. But you are right in doing the NULL check.
-
However, I don't believe passing a pointer to pointer buys you anything. It just adds indirection, which should make everything you do with the pointer slower.
Passing a pointer instead of a value gives better performance if the object is large (e.g a struct with many fields). A char* is a small thing (the size of a pointer, i.e (most probably) exactly the same size as char**).
-
I believe strlen() was written without a NULL check to make it faster, since most experienced programmers will do their own NULL checking (if there's a chance of it being NULL).
As for preventing the first crash, there's no portable way to check if a pointer has been initialized. You just have to assume the programmer knows better than that.
-
Quote:
Code:
//They said passing by reference gives better performance:
int strlen_byref(char **str)
That's not passing by reference. You cannot pass by reference in C. That's passing a pointer to a pointer, by value, and it only decreases performance.
You can't stop a crash from occurring when passing in an uninitialised pointer. Checking for NULL is the caller's responsibility, as usually the passed pointer is to a buffer and would not be NULL.
Quote:
Comments are welcome :)
Questions are welcome :)
-
>int strlen(char *str)
The library strlen() returns a size_t versus an int, which would allow for longer strings. I like strlen_simple(), but with a char *str instead of char **str as the parameter. It requires one local variable versus the first version, but I don't see where that makes it less attractive than the first version.
-
The standard C strlen() also takes a const char *, because strlen() doesn't need to modify the string that it is passed.