Weird strlen behavior

C

Chris

Hi there,

I have been reading in this group for a while really enjoy this pool
of infinite c wisdom. :)

Anyway, I have question now. I have this little piece of code that is
giving me a headache.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* Definitions */
#define STRING_LENGTH 12

/* Variables */
char str[STRING_LENGTH];
char *str1;
char *str2 = &str[0];
unsigned int i;

/* Main */
int main(void)
{
str1 = "Hello World!";

printf("String length: %d\n",strlen(str1));

for(i = 0u; i < strlen(str1); i++)
{
*str2++ = *str1++;
printf("%d\n",i);
}

puts(str);

/* Wait for key */
getc(stdin);
return EXIT_SUCCESS;
}

The problem is the strlen(str1) expression. The code compiles fine
(with latest MinGW under XP) but running the executable it gives me
the following output:

String Length: 12
0
1
2
3
4
5
Hello

It seems to break out of the loop early, after 6 iterations instead of
12.

I replace the expression with something like this:

unsigned int length;

....

length = strlen(str1);

for(i = 0u; i < length; i++)
{
*str2++ = *str1++;
printf("%d\n",i);
}

....

Then it works fine and runs 12 times and copies the entire string.

Any idea whats the problem here?

Thanks,
Chris
 
E

Eric Sosman

Chris said:
Hi there,

I have been reading in this group for a while really enjoy this pool
of infinite c wisdom. :)

Anyway, I have question now. I have this little piece of code that is
giving me a headache.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* Definitions */
#define STRING_LENGTH 12

/* Variables */
char str[STRING_LENGTH];
char *str1;
char *str2 = &str[0];
unsigned int i;

/* Main */
int main(void)
{
str1 = "Hello World!";

printf("String length: %d\n",strlen(str1));

for(i = 0u; i < strlen(str1); i++)
{
*str2++ = *str1++;
printf("%d\n",i);
}

puts(str);

/* Wait for key */
getc(stdin);
return EXIT_SUCCESS;
}

The problem is the strlen(str1) expression. The code compiles fine
(with latest MinGW under XP) but running the executable it gives me
the following output:

String Length: 12
0
1
2
3
4
5
Hello

It seems to break out of the loop early, after 6 iterations instead of
12.

I replace the expression with something like this:

unsigned int length;

...

length = strlen(str1);

for(i = 0u; i < length; i++)
{
*str2++ = *str1++;
printf("%d\n",i);
}

...

Then it works fine and runs 12 times and copies the entire string.

Any idea whats the problem here?

You keep changing what str1 points to, and hence
changing the result of strlen(str1):

i = 0, strlen("Hello world!") = 12
i = 1, strlen("ello world!") = 11
i = 2, strlen("llo world!") = 10
i = 3, strlen("lo world!") = 9
i = 4, strlen("o world!") = 8
i = 5, strlen(" world!") = 7
i = 6, strlen("world!") = 6, that's all she wrote.

Incidentally, you should be glad that your loop stopped early.
The destination array str is twelve characters long, which is
enough room for a string of *eleven* characters plus the zero
end-marker. In your modified code you copy twelve characters
from "Hello world!" to the destination, but there is no end-
marker and the destination thus doesn't hold a proper string.
Pass this malformed string to a function expecting a well-
formed string (puts(), for example), and there's no telling
what will happen.
 
C

Chris

You keep changing what str1 points to, and hence
changing the result of strlen(str1):

i = 0, strlen("Hello world!") = 12
i = 1, strlen("ello world!") = 11
i = 2, strlen("llo world!") = 10
i = 3, strlen("lo world!") = 9
i = 4, strlen("o world!") = 8
i = 5, strlen(" world!") = 7
i = 6, strlen("world!") = 6, that's all she wrote.

Doh! Thanks.
Incidentally, you should be glad that your loop stopped early.
The destination array str is twelve characters long, which is
enough room for a string of *eleven* characters plus the zero
end-marker. In your modified code you copy twelve characters
from "Hello world!" to the destination, but there is no end-
marker and the destination thus doesn't hold a proper string.
Pass this malformed string to a function expecting a well-
formed string (puts(), for example), and there's no telling
what will happen.

Thats correct. I always forget that little invisible sucker...

Thanks for the quick response.

Chris
 

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

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top