views:

101

answers:

3

I want to be clear about all the advantages/disadvantages of the following code:

{
    char *str1 = strdup("some string");
    char *str2 = "some string";
    free(str1);
}

str1:

  • You can modify the contents of the string

str2:

  • You don't have to use free()
  • Faster

Any other differences?

+1  A: 

Using the original string - whether it's a literal in the source, part of a memory-mapped file, or even an allocated string "owned" by another part of your program - has the advantage of saving memory, and possibly eliminating ugly error conditions you'd otherwise have to handle if you performed an allocation (which could fail). The disadvantage, of course, is that you have to keep track of the fact that this string is not "owned" by the code currently using it, and thus that it cannot be modified/freed. Sometimes this means you need a flag in a structure to indicate whether a string it uses was allocated for the structure or not. With smaller programs, it might just mean you have to manually follow the logic of string ownership through several functions and make sure it's correct.

By the way, if the string is going to be used by a structure, one nice way to get around having to keep a flag marking whether it was allocated for the structure or not is to allocate space for the structure and the string (if needed) with a single call to malloc. Then, freeing the structure always just works, regardless of whether the string was allocated for the structure or assigned from a string literal or other source.

R..
+1  A: 

Use neither if you can and avoid it by one of the following

static char const str3[] = { "some string" };
char str4[] = { "some string" };

str3 if you never plan to modify it and str4 if you do.

str3 ensures that no other function in your program can modify your string (string literals may be shared and mutable). str4 allocates a constant sized array on the stack, so allocation and deallocation comes with no overhead. The system has just to copy your data.

Jens Gustedt
Regarding `str3`: a string literal is of type `char[]`. What's the point of copying it to an object of type `const char[]` (and static even)? I think it would be better to just define a pointer to the literal and avoid the copy: `const char *str3 = "some string";`
pmg
`str4` had very wasteful overhead. Every time the scope of `str4` is entered, the program performs the equivalent of `strcpy(str4, "some string");`.
R..
@R.: no not exactly. The length of both `char` arrays is fixed at compile time. So it does basically a `memcpy` from a constant address to the stack. Compared to the `str1` method it saves the `malloc` behind the scenes and the `free` that one has to do somewhere. That is all that I said, I think.
Jens Gustedt
A: 
  1. strdup is not C89 and not C99 -> not ANSI C -> not portable
  2. is portable and str2 is implicit const