counting string length using recursion?

P

pembed2003

Hi all,
As an exercise, I am trying to come up with a function to count the
length of a char* string using recursion. I came up with this:

int count_length(char* s){
if(s == 0)
return 0;
else{
s++;
return 1 + count_length(s);
}
}

but it doesn't work. There is a core dump / illegal operation. I tried
to fix it by:

int count_length(char* s){
if(s == 0 || !*s)
return 0;
else{
s++;
return 1 + count_length(s);
}
}

This seems to fix the problem and return the correct length. I tested
it with:

count_length(0);
count_length("12345");

My question is: Why is the first version not work? I though the "if(s
== 0)" check will catch the null pointer, no? Can someone explain to
me? Thanks!
 
K

Kai-Uwe Bux

pembed2003 wrote:
[snip]
int count_length(char* s){
if(s == 0)
return 0;
else{
s++;
return 1 + count_length(s);
}
}

but it doesn't work. There is a core dump / illegal operation.by:
[/snip]

The end of a char string is a 0 character. This routine tests for s==0
and will not catch the end of the string indicated by *s == 0. Thus, the
pointer s will keep moving through memory until it hits a region
that your process is not allowed to access. Then the programm crashes.


Best

Kai-Uwe Bux
 
M

Mark A. Gibbs

pembed2003 said:
Hi all,
As an exercise, I am trying to come up with a function to count the
length of a char* string using recursion. I came up with this:

int count_length(char* s){
if(s == 0)
return 0;
else{
s++;
return 1 + count_length(s);
}
}

but it doesn't work. There is a core dump / illegal operation. I tried

yes, because you never stop counting.
to fix it by:

int count_length(char* s){
if(s == 0 || !*s)
return 0;
else{
s++;
return 1 + count_length(s);
}
}

This seems to fix the problem and return the correct length. I tested
it with:

yup. the test you have about now first checks to make sure that s is not
a null pointer, then checks to make sure that _what s points to_ is not
0, which denotes the end of the string.

for a clearer example, consider this:

if (s == 0) {
//s is null
}

if (*s == char(0)) { // note the cast for clarity
//s points to a null character - the end of a string
}

if you want my opinion, i'd recommend that you don't return 0 as the
length of a null pointer "string". null pointers are problematic (and
have obviously confused you slightly).

perhaps better would be:

int count_length(char* s){
assert(s != 0);

if (*s == '\0')
return 0;
else{
s++;
return 1 + count_length(s);
}
}

or if you do not want to assert, then return -1 or something. that is,
of course, unless you want to allow for null pointer "strings".

remember:
char* str = 0; // null pointer

is not the same as:
char* str = ""; // zero-length string

mark
 
P

Petec

pembed2003 said:
Hi all,
As an exercise, I am trying to come up with a function to count the
length of a char* string using recursion. I came up with this:

int count_length(char* s){
if(s == 0)
return 0;
else{
s++;
return 1 + count_length(s);
}
}

but it doesn't work. There is a core dump / illegal operation. I tried
to fix it by:

int count_length(char* s){
if(s == 0 || !*s)
return 0;
else{
s++;
return 1 + count_length(s);
}
}

This seems to fix the problem and return the correct length. I tested
it with:

count_length(0);
count_length("12345");

My question is: Why is the first version not work? I though the "if(s
== 0)" check will catch the null pointer, no? Can someone explain to
me? Thanks!

Because a null pointer is not the same as a nul character:

int strlen_r(const char* str)
{
return *str ? strlen_r(str + 1) + 1 : 0;
}

- Pete
 
P

Petec

Petec wrote:
Because a null pointer is not the same as a nul character:

int strlen_r(const char* str)
{
return *str ? strlen_r(str + 1) + 1 : 0;
}

Note that my version treats a null pointer like the standard library strlen
does: it simply dereferences the null pointer. If you want to do some error
handling for that:

int strlen_r(const char* str)
{
if(!str) throw "null pointer in strlen_r()";
return *str ? strlen_r(str + 1) + 1 : 0;
}

Then clients can catch the error:

int main()
{
const char* str = "hello, world!";
try
{
std::printf("\"%s\" length: %d\n", str, strlen_r(s));
std::printf("NULL length: %d\n", str, strlen_r(0));
}
catch(const char* ex)
{
std::printf("%s\n", ex);
}

return 0;
}

- Pete
 
J

Julie

pembed2003 said:
Hi all,
As an exercise, I am trying to come up with a function to count the
length of a char* string using recursion. I came up with this:

int count_length(char* s){
if(s == 0)
return 0;
else{
s++;
return 1 + count_length(s);
}
}

but it doesn't work. There is a core dump / illegal operation. I tried
to fix it by:

int count_length(char* s){
if(s == 0 || !*s)
return 0;
else{
s++;
return 1 + count_length(s);
}
}

This seems to fix the problem and return the correct length. I tested
it with:

count_length(0);
count_length("12345");

My question is: Why is the first version not work? I though the "if(s
== 0)" check will catch the null pointer, no? Can someone explain to
me? Thanks!

s is a pointer. Incrementing it moves to the next address. It will only be
zero after it wraps past its limit.

You need to test what s is pointing to:

int count_length(char* s){
if(!*s)
return 0;
// ...

Of course, this presumes that a valid (non NULL) string is passed in. If s can
be NULL, then your second version is most appropriate.

As a matter of clarity, it is more appropriate to write:

++s;

as opposed to:

s++;
 
P

pembed2003

Petec said:
Petec wrote:


Note that my version treats a null pointer like the standard library strlen
does: it simply dereferences the null pointer.

Thanks for everyone who answered my question:

A null pointer != A null character

Now another question for Petec:

You said the standard library strlen simply dereferences the null
pointer but won't that cause problem? Because the null pointer can not
be dereferenced right? In fact, I tried your version:

int strlen_r(const char* str)
{
return *str ? strlen_r(str + 1) + 1 : 0;
}

with:

strlen_r(0);

and the program crash. Can you explain?
 
M

Milan Cermak

pembed2003 said:
Now another question for Petec:

You said the standard library strlen simply dereferences the null
pointer but won't that cause problem? Because the null pointer can not
be dereferenced right?

Of course. The strlen function will crash the same way as Petec example
you tried. The second Petec example handles this problem and in case of
NULL pointer it throws out an exception.
 
D

Default User

Milan said:
Of course. The strlen function will crash the same way as Petec example
you tried. The second Petec example handles this problem and in case of
NULL pointer it throws out an exception.


To be precise, it probably have undefined behavior. That may be crash.
It may not be a crash. Expecting the system to bail out on UB is a
common error. Instead, the program may charge off and do all sorts of
fun things that don't involve crashing at all.




Brian Rodenborn
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top