You're not allocating what you're think you're allocating.
When you say
char **str;
this is not a variable that can hold one string. This is a variable that can hold an array of multiple strings.
When you say
int len = 1;
str = malloc(sizeof(char*) * len);
you are setting str
up to hold one string. That is, in this case, len
counts the number of strings, not the length of the string.
Then when you say
str[0] = "This is a string";
you are filling in str
's one string with a pointer to the string constant. The compiler allocated memory for the string constant for you, so you don't have to. In this case, all you're doing is copying the pointer. You're not copying the entire string, so you don't have to allocate any more memory for it. It's similar to if you just said
char *p;
p = "This is a string";
If you wanted to allocate memory for the whole string, and actually copy the whole string, it might look like this:
const char *string_to_copy = "This is a string";
str[0] = malloc(strlen(string_to_copy) + 1); /* +1 for \0 */
if(str[0] == NULL) exit(1);
strcpy(str[0], string_to_copy);
And if you wanted to use str
to hold multiple strings, it might look like this:
len = 4;
str = malloc(sizeof(char*) * len);
if(str == NULL) exit(1);
str[0] = "This";
str[1] = "is";
str[2] = "a";
str[3] = "test.";