Can't understand pointer's mem address result in C - c

I'm experiencing a mind-blowing doubt concerning the use of pointers in C. So, I've searched a lot about this, but no satisfatory answer was presented to me. Here is the thing:
I declare a pointer of type INT, and a variable of type INT (e.g int x, *pointer). So, let's suppose that both of them occupy sequential addresses in RAM, like 0x102 and 0x106, respectively. No surprises so far. Then, I declare x = 5. My memory map should be like this, shouldn't?
int x, *pointer;
x = 5;
Ok. In the college I learned to assign a pointer this way:
pointer = &x;
And my memory map should be like this:
So far so good. But the question is: if, instead of above, I assign a pointer like this:
*pointer = x;
The memory address of 'x' shouldn't be stored in the pointer's memory address? I always wondered something like the "Memory Map 2", but the result is the same of the "Memory Map 1", that is, the 0x106 address holds a garbage number. So how the program KNOWS where I'd like to point to, if the memory address of 'x' isn't stored at pointer's memory address? Where this information is stored?
It looks like a simple question, but I can't understand. :(
Thanks in advance! :)

Getting how pointers work is tricky. Here's something that might help.
You wrote
int x, *pointer;
which is not just idiomatic; this is telling you something important. It is telling you that the expression x is a variable that can hold an integer; that is hopefully clear. It is also telling you that the expression *pointer is also a variable that can hold an integer.
When you say
x = 123;
that means "store the value 123 in the variable x".
And so when you say
*pointer = 456;
that means "store the value 456 in the variable *pointer".
When you say
pointer = &x;
that means "the expression *pointer -- which remember is a variable that can hold an integer -- is the same variable as x". They are aliases -- two names for the same variable.
So your question is:
How does the program know where I'd like to point to, if the memory address of x isn't stored at pointer's memory address?
Let me rephrase that question using the terminology I've established:
How does the program know which variable *pointer refers to if I do not initialize pointer?
It does not know. If you say:
int x;
printf("%d", x);
then you can get any integer printed; this is undefined behavior. You haven't said what value you want the variable x to have, so it can have any value. When you say:
int *pointer;
*pointer = 123;
Then you are saying "store 123 in variable *pointer", but you haven't said what variable *pointer is. So, just as x can have any value, *pointer can be any variable. Again, we have undefined behavior.
Is that now clear?

int x, *pointer;
*pointer = x;
This is undefined behaviour, because pointer does not point to a valid memory location.
int x, *pointer;
x = 5;
pointer = &x;
*pointer = x;
The last line of this is basically the same as x = x, because pointer points to x;

Since * is the dereference operator, then you will try to:
store the value of x (since there's no addressof, & operator before its name)
to the memory pointed to by pointer (and not into the pointer itself, which wouldn't make sense anyway), which is indeterminate, since your pointer hasn't yet been initialized.
This is not storing the address of x into pointer; what you want is achieved solely by writing pointer = &x;, nothing else will do that. By the way, because of the assignment to the memory pointed to by an uninitialized pointer, *pointer = x invokes undefined behavior.

Doing
*somePtr = someVar
assigns the value of somevar in the place pointed by somePtr ..
To be more comprehensive,
int x = 2, y =3;
int * pointer;
pointer = &x;
*pointer = y;
asiigns the value of y in x . That's it!

Related

What is the difference between derefencing and assigning the address of a variable to pointer variable in C?

See the two codes below!
int main() {
int a = 12;
int *p;
*p = a;
}
and the this code,
int main() {
int a = 12;
int *p;
p = &a;
}
In the first piece of code dereferenced the pointer as this *p = a, and in the second piece of code, the address of variabe a is set to the pointer variable.
My question is what is the difference between both pieces of codes?
In your first piece of code:
int main() {
int a = 12;
int *p;
*p = a;
}
you have a serious case of undefined behaviour because, what you are trying to do is assign the value of a to the int variable that p currently points to. However, p has not been assigned an 'address', so it will have an arbitrary - and invalid - value! Some compilers may initialise p to zero (or NULL) but that is still an invalid address (on most systems).
Your second code snippet is 'sound' but, as it stands, doesn't actually achieve anything:
int main() {
int a = 12;
int *p;
p = &a;
}
Here, you are assigning a value (i.e. an address) to your pointer variable, p; in this case, p now points to the a variable (that is, it's value is the address of a).
So, if you appended code like this (to the end of your second snippet):
*p = 42;
and then printed out the value of a, you would see that its value has been changed from the initially-given 12 to 42.
Feel free to ask for further clarification and/or explanation.
Declaring *p and a is reserving some space in memory, for a pointer in first case, for what a is in the 2nd case (an int).
In these both cases, their values are not initialized if you don't put anything in it. That doesn't mean there is nothing in it, as that is not possible. It means their values are undetermined, kind of "random" ; the loader just put the code/data in memory when requested, and the space occupied by p, and the one occupied by a, are both whatever the memory had at the time of loading (could be also at time of compilation, but anyway, undetermined).
So you take a big risk in doing *p = a in the 1st case, since you ask the processeur to take the bytes "inside" a and store them wherever p points at. Could be within the bounds of your data segments, in the stack, somewhere it won't cause an immediate problem/crash, but the chances are, it's very likely that won't be ok!
This is why this issue is said to cause "Undefined Behavior" (UB).
When you initialized a pointer you can use *p to access at the value of pointer of the pointed variable and not the address of the pointed variable but it's not possible to affect value like that (with *p=a). Because you try to affect a value without adress of variable.
The second code is right use p = &a
The first one is bad:
int main() {
int a = 12;
int *p;
*p = a;
}
It means: put the value of variable a into location, pointed by pointer p. But what the p points? probably nothing (NULL) or any random address. In best case, it can make execution error like access violation or segmentation fault. In worst case, it can overwrite any existing value of totally unknown variable, resulting in problems, which are very hard to investigate.
The second one is OK.
int main() {
int a = 12;
int *p;
p = &a;
}
It means: get the pointer to (existing) variable a and assign it to pointer p. So, this will work OK.
What is the difference between dereferencing and assigning the address of a variable to pointer variable in C?
The latter is the premise for the first. They are separate steps to achieve the benefit of pointer dereferencing.
For the the explanation for where the difference between those are, we have to look what these guys are separately:
What is dereferencing the pointer?
First we need to look what a reference is. A reference is f.e. an identifier for an object. We could say "Variable a stands for the value of 12." - thus, a is a reference to the value of 12.
The identifier of an object is a reference for the value stored within.
The same goes for pointers. pointers are just like usual objects, they store a value inside, thus they refer to the stored values in them.
"Dereferencing" is when we "disable" this connection to the usual value within and use the identifier of p to access/refer to a different value than the value stored in p.
"Dereferencing a pointer" means simply, you use the pointer to access the value stored in another object, f.e. 12 in a instead through its own identifier of a.
To dereference the pointer the * dereference operator needs to precede the pointer variable, like *p.
What is assigning the address of a variable to a pointer?
We are achieving the things stated in "What is dereferencing a pointer?", by giving the pointer an address of another object as its value, in analogy like we assign a value to a usual variable.
But as opposed to usual object initializations/assignments, for this we need to use the & ampersand operator, preceding the variable, whose value the pointer shall point to and the * dereference operator, preceding the pointer, has to be omitted, like:
p = &a;
Therafter, The pointer "points" to the address the desired value is stored at.
Steps to dereferencing a pointer properly:
First thing to do is to declare a pointer, like:
int *p;
In this case, we declare a pointer variable of p which points to an object of type int.
Second step is to initialize the pointer with an address value of an object of type int:
int a = 12;
p = &a; //Here we assign the address of `a` to p, not the value of 12.
Note: If you want the address value of an object, like a usual variable, you need to use the unary operator of &, preceding the object.
If you have done these steps, you are finally be able to access the value of the object the pointer points to, by using the *operator, preceding the pointer object:
*p = a;
My question is what is the difference between both pieces of codes?
The difference is simply as that, that the first piece of code:
int main() {
int a = 12;
int *p;
*p = a;
}
is invalid for addressing an object by dereferencing a pointer. You cannot assign a value to the pointer´s dereference, if there isn´t made one reference before to which the pointer do refer to.
Thus, your assumption of:
In the first piece of code I dereferenced the pointer as this *p = a...
is incorrect.
You do not be able to dereference the pointer at all in the proper way with *p = a in this case, because the pointer p doesn´t has any reference, to which you are be able to dereference the pointer correctly to.
In fact, you are assigning the value of a with the statement of *p = a somewhere into the Nirwana of your memory.
Normally, the compiler shall never pass this through without an error.
If he does and you later want to use the value, which you think you´d assigned properly by using the pointer, like printf("%d",*p) you should get a Segmentation fault (core dumped).

Address of operator and L-values in c

If I run the following code:
int main(){
int x = 0;
int* y = &x;
&x = y;
}
I get the error:
lvalue required as left operand of assignment
I understand this means that when using the addressof operator, the pointer produced is not a valid lvalue, as is reflected in the c documentation.
My question simply is: why?
What is the reason that I cannot change the value of the pointer to my variable x? Is it to prevent the programmer from making mistakes, or does it fundamentally make no sense (in which case please explain why.)
In this line:
&x = y;
Sounds like you're trying to say "I want x to be stored in the address y".
When your declare a variable (x), its address (what you call "pointer value") is a constant value. It's NOT an "lvalue". ("l" for "left", a left part of an assignement operation, so something assignable.)
Also you're not meant to decide yourself where the system sets the datas in memory.
Plus, you're not even sure the "y" address is an allocated place allowed to be written by your process.
Three reasons here to not let you do that. :)
Here & operator gives you the address of the variable x and you are trying to assign something to that address, but that's not possible, it doesn't make sense.
If you want to change the value stored in x, just assign to it:
x = 5;
If you have a pointer (int*) y and you want to assign its value to x, use * operator to get the value y points to (stored in that address) and assign it to x:
x = *y;
If you want to assign the pointer y to x, it is not possible. Use another poiner for for that.
int *y1 = y;
In your code
&x = y
This line shows an error as &x is a constant pointer and hence cannot be changed after it has been initialized

How do I use pointers? in C

Im fairly new to C programming and I am confused as to how pointers work. How do you use ONLY pointers to copy values for example ... use only pointers to copy the value in x into y.
#include <stdio.h>
int main (void)
{
int x,y;
int *ptr1;
ptr1 = &x;
printf("Input a number: \n");
scanf("%d",&x);
y = ptr1;
printf("Y : %d \n",y);
return 0;
}
It is quite simple. & returns the address of a variable. So when you do:
ptr1 = &x;
ptr1 is pointing to x, or holding variable x's address.
Now lets say you want to copy the value from the variable ptr1 is pointing to. You need to use *. When you write
y = ptr1;
the value of ptr1 is in y, not the value ptr1 was pointing to. To put the value of the variable, ptr1 is pointing to, use *:
y = *ptr1;
This will put the value of the variable ptr1 was pointing to in y, or in simple terms, put the value of x in y. This is because ptr1 is pointing to x.
To solve simple issues like this next time, enable all warnings and errors of your compiler, during compilation.
If you're using gcc, use -Wall and -Wextra. -Wall will enable all warnings and -Wextra will turn all warnings into errors, confirming that you do not ignore the warnings.
What's a pointer??
A pointer is a special primitive-type in C. As well as the int type stored decimals, a pointer stored memory address.
How to create pointers
For all types and user-types (i.e. structures, unions) you must do:
Type * pointer_name;
int * pointer_to_int;
MyStruct * pointer_to_myStruct;
How to assing pointers
As I said, i pointer stored memory address, so the & operator returns the memory address of a variable.
int a = 26;
int *pointer1 = &a, *pointer2, *pointer3; // pointer1 points to a
pointer2 = &a; // pointer2 points to a
pointer3 = pointer2; // pointer3 points to the memory address that pointer2 too points, so pointer3 points to a :)
How to use a pointer value
If you want to access to the value of a pointer you must to use the * operator:
int y = *pointer1; // Ok, y = a. So y = 25 ;)
int y = pointer1; // Error, y can't store memory address.
Editing value of a variable points by a pointer
To change the value of a variable through a pointer, first, you must to access to the value and then change it.
*pointer1++; // Ok, a = 27;
*pointer1 = 12; // Ok, a = 12;
pointer1 = 12; // Noo, pointer1 points to the memory address 12. It's a problem and maybe it does crush your program.
pointer1++; // Only when you use pointer and arrays ;).
Long Winded Explanation of Pointers
When explaining what pointers are to people who already know how to program, I find that it's really easy to introduce them using array terminology.
Below all abstraction, your computer's memory is really just a big array, which we will call mem. mem[0] is the first byte in memory, mem[1] is the second, and so forth.
When your program is running, almost all variables are stored in memory somewhere. The way variables are seen in code is pretty simple. Your CPU knows a number which is an index in mem (which I'll call base) where your program's data is, and the actual code just refers to variables using base and an offset.
For a hypothetical bit of code, let's look at this:
byte foo(byte a, byte b){
byte c = a + b;
return c;
}
A naive but good example of what this actually ends up looking like after compiling is something along the lines of:
Move base to make room for three new bytes
Set mem[base+0] (variable a) to the value of a
Set mem[base+1] (variable b) to the value of b
Set mem[base+2] (variable c) to the sum mem[base+0] + mem[base+1]
Set the return value to mem[base+2]
Move base back to where it was before calling the function
The exact details of what happens is platform and convention specific, but will generally look like that without any optimizations.
As the example illustrates, the notion of a b and c being special entities kind of goes out the window. The compiler calculates what offset to give the variables when generating relevant code, but the end result just deals with base and hard-coded offsets.
What is a pointer?
A pointer is just a fancy way to refer to an index within the mem array. In fact, a pointer is really just a number. That's all it is; C just gives you some syntax to make it a little more obvious that it's supposed to be an index in the mem array rather than some arbitrary number.
What a does referencing and dereferencing mean?
When you reference a variable (like &var) the compiler retrieves the offset it calculated for the variable, and then emits some code that roughly means "Return the sum of base and the variable's offset"
Here's another bit of code:
void foo(byte a){
byte bar = a;
byte *ptr = &bar;
}
(Yes, it doesn't do anything, but it's for illustration of basic concepts)
This roughly translates to:
Move base to make room for two bytes and a pointer
Set mem[base+0] (variable a) to the value of a
Set mem[base+1] (variable bar) to the value of mem[base+0]
Set mem[base+2] (variable ptr) to the value of base+1 (since 1 was the offset used for bar)
Move base back to where it had been earlier
In this example you can see that when you reference a variable, the compiler just uses the memory index as the value, rather than the value found in mem at that index.
Now, when you dereference a pointer (like *ptr) the compiler uses the value stored in the pointer as the index in mem. Example:
void foo(byte* a){
byte value = *a;
}
Explanation:
Move base to make room for a pointer and a byte
Set mem[base+0] (variable a) to the value of a
Set mem[base+1] (variable value) to mem[mem[base+0]]
Move base back to where it started
In this example, the compiler uses the value in memory where the index of that value is specified by another value in memory. This can go as deep as you want, but usually only ever goes one or two levels deep.
A few notes
Since referenced variables are really just numbers, you can't reference a reference or assign a value to a reference, since base+offset is the value we get from the first reference, which is not stored in memory, and thus we cannot get the location where that is stored in memory. (&var = value; and &&var are illegal statements). However, you can dereference a reference, but that just puts you back where you started (*&var is legal).
On the flipside, since a dereferenced variable is a value in memory, you can reference a dereferenced value, dereference a dereferenced value, and assign data to a dereferenced variable. (*var = value;, &*var, and **var are all legal statements.)
Also, not all types are one byte large, but I simplified the examples to make it a bit more easy to grasp. In reality, a pointer would occupy several bytes in memory on most machines, but I kept it at one byte to avoid confusing the issue. The general principle is the same.
Summed up
Memory is just a big array I'm calling mem.
Each variable is stored in memory at a location I'm calling varlocation which is specified by the compiler for every variable.
When the computer refers to a variable normally, it ends up looking like mem[varlocation] in the end code.
When you reference the variable, you just get the numerical value of varlocation in the end code.
When you dereference the variable, you get the value of mem[mem[varlocation]] in the code.
tl;dr - To actually answer the question...
//Your variables x and y and ptr
int x, y;
int *ptr;
//Store the location of x (x_location) in the ptr variable
ptr = &x; //Roughly: mem[ptr_location] = x_location;
//Initialize your x value with scanf
//Notice scanf takes the location of (a.k.a. pointer to) x to know where
//to put the value in memory
scanf("%d", &x);
y = *ptr; //Roughly: mem[y_location] = mem[mem[ptr_location]]
//Since 'mem[ptr_location]' was set to the value 'x_location',
//then that line turns into 'mem[y_location] = mem[x_location]'
//which is the same thing as 'y = x;'
Overall, you just missed the star to dereference the variable, as others have already pointed out.
Simply change y = ptr1; to y = *ptr1;.
This is because ptr1 is a pointer to x, and to get the value of x, you have to dereference ptr1 by adding a leading *.

C pointers Question

For :
int *a;
a is an address where an integer can be stored.
&a is an address where a is stored.
Then, where is &a stored?
And, where is &(&a) stored?
And, where is &(&(&a)) stored?
Where does this storing of addresses stop?
If you don't explicitly write &a it will not be stored anywhere. If you do write then the address will be computed and stored either in an unnamed variable (temporary) or a named varible you write.
For example:
functionCall( &a ); // address will be in a temporary variable used for passing the parameter
int** b = &a; // address will be stored in variable b
otherFunctionCall( &&a ); // illegal, since &a is an expression operator & can't be applied to it
&a is a constant.
&(&a) is illegal.
a is not "an address where an integer can be stored". a is a variable large enough to hold the address of an integer. The only "integer" you can store directly in a is the address of an integer, viewed as an integer itself:
int *a;
int b;
a = &b;
printf("a is now %x\n", (unsigned int) a);
It is correct that a itself has an address, which is &a, but that address is not stored somewhere explicit, at runtime.
At a stretch, you might be able to store something that looks like the integer 0:
a = 0;
But this is just a shorthand syntax for "the NULL pointer", i.e. a pointer value guaranteed to not be the address of any actual object.
&a is the address of a. It is a value, result of operator & applied to a, and is not "stored", and has no address, so &(&a) is invalid. It's like 2+3.
int *a is a variable the size of a pointer, just like int b would an automatic int variable.
If this declaration is in a function, that variable is automatic and stored on the [stack](http://en.wikipedia.org/wiki/Stack_(data_structure)#Hardware_stacks) at runtime (a simple stack decrement allocates memory for it).
If the declaration is global, then 'a' is simply mapped in executable's .DATA area.
Any more & signs appended can 'create storage', because of the temporary variables you're using to hold'em ;) :
b = &a; //the address in the executable's .DATA or on the stack (if `a` auto)
c = &b; //the address of `b` on the stack, independent of `a` or `&a`
d = &c; //the address of `c` on the stack, independent of `a` or `&a`
z = &(&a); //error: invalid lvalue in unary '&'
The last line complains about the fact that & requires the operand to be a lvalue. That is, something assignable - like b and c above. (&a) as is a result of an expression which is not stored anywhere, therefore is not a lvalue.
You can keep going forever:
int value = 742;
int *a = &value;
void *b = &a;
void *c = &b;
void *d = &c;
You wouldn't put it on a single line without assigning it to anything - in that case it would be invalid.
At the crux of your problem seems to be a lack of understanding of the physical nature of memory and pointers. Not how the code works. As Im sure you know, physical memory is comprised of a large group of adjacent cells. The addresses of these cells are fixed and hard-coded by the computer itself, not by software apps or the programming language that you use. When you refer to &a, you are referring to the physical block of memory that is currently holding your value you've stored within the computers ram. "a" is simply a name that you've given the computer so that it knows exactly what block of memory to find the value that you've stored. I think that pretty much covers memory address.
Lets go over pointers now. A pointer is yet another memory address, that is referred to by the computer. It has whatever name that you give it. In this case it should be called something else besides the same name that you gave your first value. Lets call it "b". Based on how you declared it. b's memory location is only capable of holding one type of data....another memory location.... so when I say: b= &a I'm saying that the memory address of 'b'(which is designed only to hold memory addresses), is to hold the memory address of 'a'. Meanwhile on the other side of town, the memory address of 'a' has an integer stored in it.
I hope that this didnt get confusing, I tried not to get all techno-babble on you here. If youre still confused. Post again, Ill explain with code next time.
-UBcse
In C, a variable x may act as a value (on the right hand side of =, where it is called an rvalue), or it may act as a container for values (on the left hand side of =, where it is called an lvalue). You may take the address of x, because you can take the address of any lvalue—this gives you a pointer to the container. But because a pointer is an rvalue, not a container, you can never take &(&x). In fact for any lvalue l, &l is legal but &(&l) is never legal.
a is a variable of type "address of int";
&a is the address of variable a;
&(&a) would be the address of the address of variable a, which makes no sense
Not quite. a is a variable in which an address of some integer may be stored. &a is the address of a, i. e. the address of the variable a, which may contain an address of some integer.
Very Important: until and unless an address of something is assigned to a, it is an uninitialized pointer. Trying to use whatever it points to will lead to unpredictable results, and will likely crash your program.
You can have a pointer to a pointer.
Ex:
void foo(int **blah)
{
int *a = *blah;
...
}
A pointer does take up memory. It's just a small container that holds the address of something. It just can't take up "no space" because everything in the computer is represented somehow by numbers. It's just that as far as C/C++ is concenred, int *a is simply a pointer to an object and takes up no space. That is to keep you from having to manage any sort of memory... it keeps the machine seperated from the code.
int *a; is a pointer to an int called 'a'.
&a; is the derefrence of int *a. it's pointing to itself. this is what you would use to point to the variable that you wanted to pass around from function to function. derefrence is just a fancy word for "getting the address back"
&(&(&a)) is not a valid expression as previously stated. you may make a pointer to a pointer to a pointer. That may be what your thinking of. In such a case you would derefrence the last pointer in question and the computer should understand what you're talking about.
To answer the "where is 'a' stored" question; on the stack.
please, if i'm incorrect on anything, let me know.
&a is a number which is an rvalue: you can store it somewhere if you want to in a variable you will have declared or allocated, of type int*.
To wit:
int a = 42;
&a; /* this does not store the address of a because you've not assigned the value to a variable */
int **aptr = &a; /* aptr is on the stack */
int **aptr2 = (int*)malloc(sizeof(int*));
aptr2 = &a; /* aptr2 is in the heap */
&(&a) is not legal syntax.
If you want a pointer to a pointer to an int:
int b = 39;
int *bptr = &b;
int **ptr2bptr = &bptr;
You have to build up the levels of indirection.
With the above you can then do this if you want:
printf("%d\n", *aptr);
printf("%d\n", *aptr2);
printf("%d\n", *bptr);
printf("%d\n", **ptr_to_bptr);
Producing output of:
42
42
39
39
int* a;
This line simply declares a pointer to an integer. That pointer has a memory location, which you can get the address of using &a. & is an operator that returns the address of whatever it is run on. But if you do not assign this value anywhere, there is no further &-ing possible.
As to your question as to where &a is stored, most likely in a register. If you do not use the value, it will be immediately discarded. (And registers do not have memory addresses, which is why you cannot do &(&a))

Why is the following C code illegal?

Consider a typical environment, why is the following code illegal in C?
{
int x;
&x = (int*) malloc(3*sizeof(int));
...
}
You can't assign something to the address of x because he address of x is not an lvalue
(An lvalue is "something that can be assigned to", i.e. it cannot be on the Left side of an equals sign)
Try
int* x;
x = (int*) malloc(3*sizeof(int)); // TODO: Call free(x)
Now x points to your allocated memory and you can do things like
int foo = *x;
int bar = x[0];
You can assign the address of x to something else, by using the & operator this way:
int x = 1;
int* y = &x; // y now holds the address of x
*y = 2; // Now x = 2
Becauase the address of x is not an lvalue - it is not something that can be modified. C allows you to change things that addresses point to - it does not allow you to change the addreses themselves.
Everyone is correct. The address of X at the time your code executes is a CONSTANT. In other words it says "Hey you can CHANGE where I, the compiler, store the 'x' variable."
you could do this
int main()
{
int* x;
*(&x) = malloc(3*sizeof(int));
}
The address of a variable cannot be changed. Instead you most likely want something like this:
int *x = (int *)malloc(3 * sizeof(int));
...
free(x);
&x returns pointer to x. You can't use it in the left part of an assignment, only on the right.
If you want to assign something to a pointer you have to declare it as a pointer, just like int *x;
Not that this is entirely valuable, but since no one else brought it up (all the above answers are correct, btw, and redundant, I agree that people should vote the right answer up, rather than saying the same thing over and over).
In your example, x is a stack variable. malloc gives you heap memory. That's probably not anything you need to think about too much in today's programming, but if you ever work in an environment where memory is at a premium, you'll want to save your stack as much as possible.
It's also worth noting that for some reason you're allocating 3*sizeof(int). Even if you COULD allocate memory to the stack, in your example, since you're only trying to get 1 int you'd only need 1* sizeof(int), the rest would be wasted.
That's the way the language is designed. To do what you want, use a pointer.

Resources