Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using malloc to initialize char pointer VS not using malloc and just assign a string directly to the char pointer

I'm trying to understand how this memory allocation thing works when it comes to char and strings.

I know that the name of a declared array is just like a pointer to the first element of the array, but that array will live in the stack of the memory.

On the other hand, we use malloc when we want to use the heap of the memory, but I found that you can just initialize a char pointer and assign a string to it on the very same declaration line, so I have some questions regarding this matter:

1) If I just initialize a char pointer and assign a string to it, where is this information living? In the heap? In the stack? Ex: char *pointer = "Hello world";

2) I tried to use malloc to initialize my char pointer and use it later to assign a string to it, but I can't compile it, I get error, what is wrong with this logic? this is what I'm trying to do:

char *pointer = malloc(sizeof(char) * 12); *pointer = "Hello world";

Can you please help me understand more about pointers and memory allocation? Thank you very much! :)

like image 925
Kenji Emura Avatar asked Jun 07 '26 06:06

Kenji Emura


2 Answers

1) If I just initialize a char pointer and assign a string to it, where is this information living? In the heap? In the stack? Ex: char *pointer = "Hello world";

Neither on the stack or on the heap. "Hello world" is a string literal, generally created in the rodata (read-only data) segment of the executable. In fact, unless you specify differently, the compiler is free to only store a single copy of "Hello world" even if you assign it to multiple pointers. While typically you cannot assign strings to pointers, since this is a string literal, you are actually assigning the address for the literal itself -- which is the only reason that works. Otherwise, as P__J__ notes, you must copy strings from one location to another.

2) I tried to use malloc to initialize my char pointer and use it later to assign a string to it, but I can't compile it, I get error, what is wrong with this logic? this is what I'm trying to do:

char *pointer = malloc(sizeof(char) * 12);
*pointer = "Hello world";

You are mixing apples and oranges here. char *pointer = malloc (12); allocates storage for 12-characters (bytes) and then assigns the beginning address for that new block of storage to pointer as its value. (remember, a pointer is just a normal variable that holds the address to something else as its value)

For every allocation, there must be a validation that the call succeeded, or you will need to handle the failure. Allocation can, and does fail, and when it fails, malloc, calloc * realloc all return NULL. So each time you allocate, you

char *pointer = malloc(12);       /* note: sizeof (char) is always 1 */
if (pointer == NULL) {            /* you VALIDATE each allocation */
    perror ("malloc-pointer");
    return 1;
}

Continuing with your case above, you have allocated 12-bytes and assigned the starting address for the new memory block to pointer. Then, you inexplicably, derefernce pointer (e.g. *pointer which now has type char) and attempt to assign the address of the string literal as that character.

*pointer = "Hello world";    /* (invalid conversion between pointer and `char`) */

What you look like you want to do is to copy "Hello world" to the new block of memory held by pointer. To do so, since you already know "Hello world" is 12-characters (including the nul-terminating character), you can simply:

memcpy (pointer, "Hello world", 12);

(note: if you already have the length, there is no need to call strcpy and cause it to scan for the end-of-string, again)

Now your new allocated block of memory contains "Hello world", and the memory is mutable, so you can change any of the characters you like.

Since you have allocated the storage, it is up to you to free (pointer); when that memory is no longer in use.

That in a nutshell is the difference between assigning the address of a string literal to a pointer, or allocating storage and assigning the first address in the block of new storage to your pointer, and then copying anything you like to that new block (so long as you remain within the allocated bounds of the memory block allocated).

Look things over and let me know if you have further questions.

like image 133
David C. Rankin Avatar answered Jun 10 '26 04:06

David C. Rankin


1) If I just initialize a char pointer and assign a string to it, where is this information living? In the heap? In the stack? Ex: char *pointer = "Hello world";

The string literal "Hello world" has static storage duration. This means it exists somewhere in memory accessible to your program, for as long as your program is running.

The exact place where it is located is implementation specific.

2) I tried to use malloc to initialize my char pointer and use it later to assign a string to it, but I can't compile it, I get error, what is wrong with this logic? this is what I'm trying to do:

char *pointer = malloc(sizeof(char) * 12);
*pointer = "Hello world";

This doesn't work, since *pointer is the first char in the dynnamically allocated memory (returned by malloc()). The string literal "Hello world" is represented as an array of characters. An array of characters cannot be stored in a single char.

What you actually need to do in this case is copy data from the string literal to the dynamically allocated memory.

char *pointer = malloc(sizeof(char) * 12);
strcpy(pointer, "Hello world");            /* strcpy() is declared in standard header <string.h> *

Note that this doesn't change the data that represents the string literal. It copies the data in that string literal into the memory pointed at by pointer (and allocated dynamically by malloc()).

If you really want pointer to point at the (first character of) the string literal, then do

const char *pointer = "Hello world";

The const represents the fact that modifying a string literal gives undefined behaviour (and means the above prevents using pointer to modify that string literal).

If you want to write really bad code you could also do

char *pointer = "Hello world";   /*  Danger Will Robinson !!!! */

or (same net effect)

char *pointer;
pointer = "Hello world";     /*  Danger Will Robinson !!!! */

This pointer can now be used to modify contents of the string literal - but that causes undefined behaviour. Most compilers (if appropriately configured) will give warnings about this - which is one of many hints that you should not do this.

like image 44
Peter Avatar answered Jun 10 '26 02:06

Peter



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!