Lion King
Lion King

Reputation: 33813

Unknown symbols appear when printing the result

I have two ways to do the same purpose, the first-way prints unknown symbols and the second-way prints exactly what I want.

The first-way:

const char *constStr = "Hello world";
char *str = (char*) malloc(strlen(constStr) + 1), *p = str;
while (*constStr) {
    *p = *constStr;
    constStr++;
    p++;
}
printf("%s\n", str);
free(str);

The result:

The second-way:

const char *constStr = "Hello world";
char *str = (char*) malloc(strlen(constStr) + 1);
for (int i = 0; i <= strlen(constStr); i++) {
    str[i] = constStr[i];
}
printf("%s\n", str);
free(str);

The result:

Why the first-way the result seems strange?

Upvotes: 2

Views: 449

Answers (2)

user2736738
user2736738

Reputation: 30926

No you didn't null terminate the string. This is undefined behavior to pass pointer to non-null terminated char array in printf using %s format specifier.

Outside the loop make *p=0. That will null terminate the char array.

Second way is printing because you copied the \0 which is in strlen(constStr) index of the array. Notice the <= in the loop condition.

From where those weird letters come?

Think in terms of printf. When it sees the %s format specifier it prints starting from the address provided to it as argument. Now when does it stop? when it finds the \0. here it didnt find it and it read out of the memory that you allocated. Those bit patterns on those memory turned out to be those non printable characters. That's what you saw. The correct way to do this would be:

const char *constStr = "Hello world";
char *str = malloc(strlen(constStr) + 1), *p = str;
while (*p++ = *constStr++); // here `\0` will be copied.
printf("%s\n", str);
free(str);

When working with strings make sure you keep the corner cases clean. By that I mean,check whether the \0 is copied or not etc. This is so common a problem when we implement string routines.

Upvotes: 1

smac89
smac89

Reputation: 43128

To fix the first one, add a null at the end of the string:

const char *constStr = "Hello world";
char *str = (char*) malloc(strlen(constStr) + 1), *p = str;
while (*constStr) {
    *p = *constStr;
    constStr++;
    p++;
}

*p = '\0'; /* <-- HERE */

printf("%s\n", str);
free(str);

Note: you are modifying a pointer to a temporary - not recommended. Use the same approach as you did for str, by using a another pointer which gets shifted.

Upvotes: 1

Related Questions