Question

The following code always segfaults:

  char *test3 = (char *) malloc(sizeof(char) * 5);
  test3 = "asdf";
  printf("%s\n", test3);

The following code does not segfault:

  char *test3 = (char *) malloc(sizeof(char) * 5);
  test3[0] = 'a';
  test3[1] = 'b';
  test3[2] = 'c';
  test3[3] = 'd';
  test3[4] = '\0';
  printf("%s\n", test3);

I guess the question may be how do I assign a cstring literal to dynamically created cstring?

Was it helpful?

Solution

The correct way to "fill" a string is:

 strcpy(test3, "abcd"); 

However, I would strongly recommend that you don't use malloc [and DEFINITELY don't use (char *) malloc(...) - since that can hide some rather nasty bugs that jump up and bite you at least opportune moment, as bugs do have a tendency to do that - you are probably doing that because you are compiling your C-code as C++-code, which is wrong, and teaches you bad habits like this one].

Using malloc to allocate small strings is a large waste of space. Your 5 character string probably has an overhead of 16-32 bytes, and will be rounded to 8 or 16 bytes. So in total it could be using 48 bytes, to store 5 bytes - that's a BIG waste of space.

OTHER TIPS

Others have (correctly) suggested you copy the string into the allocated memory.

Here's why your approach is segfaulting: The string "asdf" is a string literal, and at compile time it gets stored in rodata, or read-only data. When your program tries

test3 = "asdf";

It attempts to create a pointer to rodata. C does not allow pointers into rodata, and so your statement not only doesn't work, but seg faults.

The second method was fine, because you're not modifying the pointer, but rather what it points to.

First of all, thank-you for this question it has an interesting wrinkle.

I ran your code with Eclipse/Microsoft C and did NOT get a segmentation error and it printed "asdf" as expected.

However, this does NOT mean or imply that you are not getting a segmentation fault. Your result implies an examination of how a compiler implements the two statements:

   char *test3 = (char *) malloc(sizeof(char) * 5);

Allocates storage on the heap and sets the pointer, test3, to point to that location. The next statement also updates the same pointer.

   test3 = "asdf";

However, in this case test3 points to the literal "asdf" where-ever that literal is stored. Some compilers generate a literal pool of strings and store them somewhere in the executable, as such for some compilers these literals cannot be modified.

So why would the compiler store a literal where it cannot be accessed? Doesn't make sense, hence the question: what C compiler are you using? And what version of C is it adhering to??

To work around what might be a compiler bug, and still point test3 at a literal, try?? (Again, C compilers do differ on what and how they implement language constructs.)

  const char *literal = "asdf";  // also try without a const stmt 
  // other code here
  test3 = literal;

Finally, in the second example the storage on the heap that was malloced is being modified and is obviously addressable.

You can't assign a string value with a "=" in your case.

You need to use the strcpy or sprintf function. At the end of the program (or when the string is not used anymore) do not forget to free it ! For example :

#define BUFSIZE 5

int main(void) {
    char *test3 = malloc(sizeof(char) * BUFSIZE);
    snprintf(test3,BUFSIZE,"test");
    printf("%s\n", test3);
    free(test3);
    return 0;
}

Or you can just write :

int main(void) {
    char buf[BUFSIZE] = "test";
    printf("%s\n", buf);
    return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top