#include <stdlib.h>
main(){
int *num;
num = malloc(sizeof(int));
}
If malloc()
returns a pointer and num
is a pointer too, then does that mean that we have two pointers in the end? The returned pointer by malloc()
simply acts as a "dummy" pointer so that num
can point to the new memory allocation. Similar to doing x=y
, where both are pointers.
By "dummy" I mean that you could use malloc(sizeof(int))
as a pointer if casted to the correct type without needing to define a pointer to assign it to, but that would be too much.
#include <stdlib.h>
#include <stdio.h>
main(){
printf("%d", ((int *) malloc(3*sizeof(int)))[1] = 33);
}
What I'm trying to says is this. malloc()
returns an unnamed pointer, so we can't reference it. This means that we need another pointer that is named so that we can reference it and access the memory location. This is done by using =
. This is similar to doing this.
#include <stdio.h>
main() {
int* x;
int* y;
x = malloc(sizeof(int));
*x = 42;
y = x;
*y = 13;
printf("%d", *x)
}
To be more specific,
y = x;
CodePudding user response:
The key thing to note here is that a pointer in C is a variable, but all it "contains" is the memory address where the actual value is located. So int *num
means "this variable is a memory address whose location contains an 'int' type value". When you first declare it int *num;
it doesn't point to anything... it's just a junk value. In modern C/C you'd really want to initialize it to something, even if it's just zero: int * num = NULL;
.
Of the course the variable
num
itself exists in memory somewhere, typically on the local stack or it could be a machine register.
When you call malloc
that function goes to the operating system and gets more memory for your program, and then returns the memory address of that new memory. In the case of malloc(sizeof(int))
you are telling it to allocate enough bytes to hold an int
(on a typically PC this is probably 4 bytes).
In C/C the program is now responsible for managing the memory returned by
malloc
, and is expected to callfree
on it eventually.
When your program executes the statement num = malloc(sizeof(int));
, it's getting a few bytes of new memory allocated to your program, then returning the memory address of the new memory location, and then storing that memory address in the variable num
. If there was any value there before it's overwritten. In the code above, that's fine because num
didn't point to anything valid in the first place. That said, you have not actually put anything into the new memory location, so that that point you have a valid pointer num
with the address of a memory location allocated by malloc
that itself contains some junk integer value.
I have to say that printf("%d", ((int *) malloc(3*sizeof(int)))[1] = 33);
is an extremely creative line of C code, although it's really terrible code :) This statement does the following:
it calls malloc which allocates enough space for 3 integers (let's say 12 bytes). The address of the new memory location is then returned by that function.
You then "deference" that memory with the
[1]
index operator and set the second integer in that newly allocated 3-int block of memory to the value 33.Because of the way C/C works, the value 33 is then passed as an argument to the printf function, leaking that allocated 12 bytes which you can't ever get back again because you never kept the memory location returned by
malloc
. Furthermore, the first and third values in that memory location are uninitialized so they contain junk.
IOW it's the same as printf("%d", 33);
with a side-effect of leaking 12 bytes of memory, one location of which contains 33 but you have no idea where it's located in memory.
CodePudding user response:
Yes, you can totally use the return value from malloc directly without assigning it to some variable.
There is just one tiny problem: You have to free the pointer eventually. If you don't assign it to a variable then there is basically only one way to do that:
free(malloc(sizeof(int)));
and what use would that be?