0

Can u explain how the memory of the below gets allocated to hold such big string even though am giving size of malloc to be only one byte

char **str;
int len = 1;
str = malloc(sizeof(char*)*len);//wont this allocate only one byte in heap?
str[0] = "This is a string";//this is more than one byte
printf("%s",str[0]);

am pretty confused as to how it is working.

Meghana
  • 49
  • 5
  • You aren't allocating 1 byte. You are allocating a pointer - probably 4 or 8 bytes. Then you assign it to a const string that already exists elsewhere. – 001 Jul 08 '16 at 13:16
  • Why do you think `malloc()` will allocate "only one byte"? – babon Jul 08 '16 at 13:27
  • "Why does this obviously invalid program work?" In general, this kind of question is not productive. Read on "undefined behavior". (This particular program may or may not be invalid). – n. m. could be an AI Jul 08 '16 at 13:33
  • `str[0] = "This is a string";` doesn't make physical copy. To make copy use function `strcpy(...)`. – Beka Jul 08 '16 at 13:36

2 Answers2

3

You are not allocating one byte.

The expression sizeof(char*)*len can be simplified to sizeof (char *), i.e. the size of a character pointer. This is typically 4 or 8.

Then you just store a single pointer there, the value of the string literal "This is a string" is the address where that literal appears in memory, so this:

str[0] = "This is a string";

just does a single pointer-sized assignment to str[0] (which is a pointer), no characters are copied. Exactly one pointer is how much space you've allocated, so it all works out nicely.

unwind
  • 391,730
  • 64
  • 469
  • 606
0

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.";
Steve Summit
  • 45,437
  • 7
  • 70
  • 103