Kingamere
Kingamere

Reputation: 10132

C copying to a string created from malloc

I have this code:

char *name = malloc(strlen(args[1]) + 6);
strncpy(name, args[1], strlen(args[1]));
printf("%d\n", strlen(name));

Let's say args[1] is "hello" and so strlen(args[1]) is 5. After malloccing 11 bytes, I then copy 5 bytes of "Hello" (meaning I want to exclude the null terminating byte) to name.

But strlen(name) isn't 5. I get 8. Shouldn't it be 5 since you that's what you copied over?

Upvotes: 0

Views: 133

Answers (3)

M.M
M.M

Reputation: 141618

This code uses strncpy incorrectly. The strncpy function is an unsafe version of strcpy and should be avoided; using it correctly requires writing unnecessarily complicated code.

Instead you can write:

char *name = malloc(strlen(args[1]) + 6);
strcpy(name, args[1]);
printf("%zu\n", strlen(name);

Upvotes: 2

Adam
Adam

Reputation: 17339

Copy like this instead:

strncpy(name, args[1], strlen(args[1]) + 1);
                                      ^^^^

or specify n = length of name - 1.

The string "hello" takes 6 bytes: 5 letters and the null terminator. When you tell strncpy to copy at most 5 bytes (that's what strlen(args[1]) in your code does) then it will do just that: copy the letters and it won't write the null terminator.

That means name is not a valid string, and calling strlen(name) is undefined behavior. In your case there just happens to be a zero byte so strlen returns 8.

In my opinion this behavior of strncpy is poor design, but that's the way it is.

Upvotes: 0

David Schwartz
David Schwartz

Reputation: 182779

If you exclude the null-terminating byte, you don't have a string. So you can't pass it to strlen and expect to get sensible results.

Upvotes: 0

Related Questions