Given:
char test[] = "bla-bla-bla";
Which of the two is more correct?
char *test1 = malloc(strlen(test));
strcpy(test1, test);
or
char *test1 = malloc(sizeof(test));
strcpy(test1, test);
Given:
char test[] = "bla-bla-bla";
Which of the two is more correct?
char *test1 = malloc(strlen(test));
strcpy(test1, test);
or
char *test1 = malloc(sizeof(test));
strcpy(test1, test);
This will work on all null-terminated strings, including pointers to char
arrays:
char test[] = "bla-bla-bla";
char *test1 = malloc(strlen(test) + 1);
strcpy(test1, test);
You won't get the correct size of the array pointed to by char*
or const char*
with sizeof
. This solution is therefore more versatile.
Neither:
#include <string.h>
char *mine = strdup(test);
You should use strlen
, because sizeof
will fail silently if you change test to be a run-time defined string. This means that strlen
is a far safer idea than sizeof
as it will keep working.
char test[]="bla-bla-bla";
char *test1 = malloc(strlen(test) + 1); // +1 for the extra NULL character
strcpy(test1, test);
I think sizeof
is the correct one. Reason behind that is strlen(str)
will give you length of the string( excluding the terminating null). And if you are using strcpy
, it actually copy the whole string including the terminating null, so you will allocate one byte less if you use strlen
in malloc
. But sizeof
gives the size of the string pointed by test, including the terminating null, so you will get correct size malloc
chunk to copy the string including the terminating null.
1) definitely causes UB
2) may cause UB (if malloc
fails)
I'd go with 2) as there is a better chance of the construct working as intended; or even better I'd write a version that works as intended (without UB) in all situations.
Edit
Undefined Behaviour in 1)
test1
will have space for the characters in test
, but not for the terminating '\0'
. The call to strcpy()
will try to write a '\0'
to memory that does not belong to test1
, hence UB.
Undefined Behaviour in 2)
If the call to malloc()
fails to reserve the requested memory, test1
will be assigned NULL
. Passing NULL
to strcpy()
invokes UB.
The return value of calls to malloc()
(and calloc()
and friends) should always be tested to ensure the operation worked as expected.
(1) with strlen
but not adding 1 is definitely incorrect. If you add 1, it would have the added benefit that it also works for pointers, not just arrays.
On the other hand, (2) is preferred as long as your string is actually an array, as it results in a compile-time constant, rather than a call to strlen
(and thus faster and smaller code). Actually a modern compiler like gcc
can probably optimize the strlen
out if it knows the string is constant, but it may be hard for the compiler to determine this, so I'd always use sizeof
when possible.
If it is a critical path, sizeof
has advantage over strlen
as it has an O(1) complexity which can save CPU cycles.