Search code examples
cstringdynamic-memory-allocationliteralsc-strings

Allocating memory for strings dynamically


char* test() {
    char* returnValue = "test";
    return returnValue;
}  
char* test=test();
printf("%s",test);

is it safe to use? is it the same, as

char* test {
    char* returnValue=strdup("test");
    return returnValue;
}
char* test=test();
printf("%s",test);

if yes, then should I free it later on? they are both seem to work correctly.


Solution

  • is it the same

    No, it isn't.


    char * test1() {
      char * returnValue = "test";
      return returnValue;
    }  
    

    The above code returns the fixed address to the constant literal "test". This will be the same address each time the function is called.

    It is not a dynamical allocation of memory.

    Doing

    printf("%d\n", test1() == test1());
    

    will print

    1
    

    meaning "true", the two addresses returned are the same.

    On "constness"

    To better reflect the constness of the result of test1() it should better be defined as follows:

    const char * test1() {
      const char * returnValue = "test";
      return returnValue;
    }  
    

    char * test2 {
      char * returnValue = strdup("test");
      return returnValue;
    }
    

    The above code returns the address to a freshly allocated area of memory having been copied "test" into. This will be a different*1 address each time the function is called.

    *1: "different" at least, as long as the result of any previous call to test2() had not been free() ed already

    This is a dynamical allocation of memory. It therefore requires a call to free() passing in the address returned by strdup() (which internally calls malloc()) to deallocated the memory, if not needed any more.

    Doing

    printf("%d\n", test2() == test2()); /* leaks memory: 2 times 4+1 char */
    

    will print

    0
    

    meaning "false", the two addresses returned are different.

    For completeness: To avoid the leak as per the above snippet do

    char * p, * q;
    printf("%d\n", (p = test2()) == (q = test2()));
    free(p);
    free(q);
    

    is it saft to use

    Formally the code of both snippets is correct.

    Which one to use and if the use if "safe" completely depends on the use case, on the the context.