I've been studying pointers for a while and I can't seem to wrap my head around it fully. There seems to be a gap that isn't explained when you jump from tutorials explaining pointers to actual functions and code that assume you know about them. The piece of code that is annoyning me is as follows:
char **output_str = malloc(sizeof(char*));
Alright, so my understanding is as follows,
**output_str is a character
*output_str is a pointer to a character
output_str is a pointer to a pointer to a character
From what I know malloc() returns a pointer to the start of the memory that has just been allocated which has a size value equal to the size of a pointer to a character(char*). Now, shouldn't a pointer to the start of the memory have a single *? If so, how can we assign something with a * to a **? I'm quite confused, if anyone could provide some clarification and maybe with some insight into the memory part that would very nice.
Your code block is correct. With this declaration:
char **output_str = malloc(sizeof(char*));
output_str is a char pointer to a char pointer, or it could be seen as a 2d array of chars, or a matrix of char.
Memory Address | Stored Memory Address Value
----------------------------------------------
0 | .....
1 | .....
2 | .....
3 | .....
4 | .....
5 | .....
6 | .....
. | .....
. | .....
. | .....
n-1 | .....
Imagine the memory as being a very big array in which you can access positions by its memory address (in this case we've simplified the addresses to natural numbers. In reality they're hexadecimal values). "n" is the total amount (or size) of the memory. Since Memory counts and starts in 0, size is equivalent to n-1.
char **output_str = malloc(sizeof(char*));
The Operating System and the C compiler does it for us, but we can think that our memory has been changed. E.g. Memory address 3 now has a char pointer to a char pointer called output_str
. .
Memory Address | Name - Stored Memory Address Value (it points to ...)
-----------------------------------------------------
0 | .....
1 | .....
2 | .....
3 | output_str = undefined
4 | .....
5 | .....
6 | .....
. | .....
. | .....
. | .....
n-1 | .....
*output_str = malloc(sizeof(char));
The memory has been changed again. E.g. Memory address 0 now has a char pointer called *output_str
.
Memory Address | Name - Stored Memory Address Value (it points to ...)
-----------------------------------------------------
0 | *output_str = undefined
1 | .....
2 | .....
3 | output_str = 0
4 | .....
5 | .....
6 | .....
. | .....
. | .....
. | .....
n-1 | .....
char a = 'a';
So again our memory has changed, it has placed at MemoryAddress[6] = 'a':
Memory Address | Name -> Stored Memory Address Value (it points to ...)
------------------------------------------------------
0 | *output_str = undefined
1 | .....
2 | .....
3 | output_str = 0
4 | .....
5 | .....
6 | a = 'a' // 'a'is static memory
. | .....
. | .....
. | .....
n-1 | .....
Lastly, we invoke
*output_str = &a;
we are now telling char pointer*output_str
to point to/reference the previously instantiatedchar a
.
So our final memory will look like this:
Memory Address | Name - Stored Memory Address Value (it points to ...)
-----------------------------------------------------
0 | *output_str = 6
1 | .....
2 | .....
3 | output_str = 0
4 | .....
5 | .....
6 | a = 'a' // 'a'is static memory
. | .....
n-1 | .....
Now printf("Value: " + a) will output "Value: a" printf("Value: " + *output_str[0]) will also output "Value: a" And printf("Value: " + **output_str) will output "Value: a"
That's a genuine doubt. I will try best to make it clear for you.
From the details in your question, I am assuming (read, "pretty sure") that you understand malloc
ating a memory and the respective return type.
You have a doubt that if malloc
returns a pointer (void*
), how can it be converted to a pointer to pointer (char**
).
char **output_str
is equivalent to char *(*output_str)
which means *output_str
is a pointer to some data of type char
. So, this is what malloc
is returning to it.malloc
returning a pointer. But essentially, you have a allocated memory for a pointer to char (char*
), that "literally" means that, malloc
is returning a pointer (void*
) to a memory where you have char*
, that makes it, a pointer to pointer to char
, i.e., char**
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With