C memory stack and heap - c

#include <stdio.h>
#include <stdlib.h>
int main (void) {
int a = 5, *ptr;
ptr = &a;
printf("0x%X\n", ptr);
printf("%p\n", &ptr); //Why are these the same?
printf("%d\n", *ptr);
ptr++;
printf("0x%X\n", ptr);
printf("%p\n", &ptr); //Why are these the same?
printf("%d\n", *ptr);
return 0;
}
Why are those two values the same? Since I incremented the pointer shouldn't the address change as well?

you incremented ptr's value. It still resides in the same place in memory. &ptr tells you its address. This is no different than doing something like a++. If you print out a's value, it will now be 6, but if you print out the address of a with printf("%p\n", (void*)&a);, it will be the same before and after the increment.

5 is the value of a and &a is the address of a.
ptr = &a means address of a equals the value of ptr.
&ptr is the address of ptr.
You can think of ptr as a box that can hold an address as it's value.
When you increment ptr you change the address held inside the box i.e. ptr; not the address of the box itself.

Related

When I point a pointer to an array. Why does the pointer and the index[0] of the array I am pointing to have different memory addresses?

#include <stdio.h>
int main()
{
int arr[5];
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
int *p = &arr;
printf("Memory address of first index: %p\n", &arr[0]);
printf("Memory address of pointer: %p\n", &p);
return 0;
}
OUTPUT
Memory address of first index: 000000000061FE00
Memory address of pointer: 000000000061FDF8
They are are not the same. Is my machine bad?
First of all the compiler should issue a message relative to this declaration
int *p = &arr;
The problem is that the right hand side expression has the type int( * )[5] while the initialized object has the type int * and there is no implicit conversion between these two pointer types.
You should write either
int *p = arr;
In this case the array designator is implicitly converted to a pointer to its first element. Or
int ( *p )[5] = &arr;
The pointer p occupies its own extent of memory. So its address is different from the address of the extent of the memory occupied by the array arr.
On the other hand, if you will output the value stored in the pointer p like for example
printf("Memory address stored in the pointer p: %p\n", ( void * )p);
then it will be equal to the address of the first element of the array arr
printf("Memory address of first index: %p\n", ( void )&arr[0]);
arr is an array. It and its elements start at some place in memory.
p is a pointer to the array. Its value is an address. That address needs to be stored somewhere else in memory. That place is different from where the array is stored.
printf("%p\n", (void *) p); prints the value of p, which will be the address of arr (and of &arr[0], since the first element is at the start of the array).
printf("%p\n", (void *) &p) prints the address of p, which is where p is.

Difference in ptr,&ptr,&ptr[0]

Below is the test code:
#include <stdio.h>
int funtion(int *ptr)
{
int temp;
temp = *ptr;
printf("ptr = %p %p %p %d\n", ptr, &ptr, &ptr[0], *ptr);
printf("*ptr = %d\n", *ptr);
return temp;
}
int main()
{
int i = 10;
int *tp = &i;
printf("tp = %p %p %p %d\n", tp, &tp, &tp[0], *tp);
(void)funtion(tp);
return 0;
}
answer:
tp = 0x7ffc1117392c 0x7ffc11173930 0x7ffc1117392c 10
ptr= 0x7ffc1117392c 0x7ffc111738f8 0x7ffc1117392c 10
*ptr =10
**question:
what are the difference between tp &tp &tp[0]
Which passing parameter we should use.
is this difference only for passing parameter?**
You are passing an int pointer to function. This is passed by value. Of course, the value they point to is the same.
int funtion(int *ptr)
{
int temp = *ptr;
printf("ptr = %p %p %p %d\n", ptr, &ptr, &ptr[0], *ptr);
printf("*ptr = %d\n", *ptr);
return temp;
}
temp is initialized with the value pointed to by ptr.
The first thing you print is ptr: the memory address you passed to function by value.
The second thing you print is &ptr. This is the address of that function argument. While this may be the same between function calls due to implementation-specific handling of the stack, it may also be different.
The third thing you print is &ptr[0]. This is the address is ptr[0], which is equivalent to writing *(ptr + 0) or just *ptr. Getting the address of this in turn is equivalent to just writing ptr.
The fourth thing you print is *ptr. Again, as with initializing temp this is just the int value that ptr points to.
1. what are the difference between tp &tp &tp[0]
Its their type.
The type of tp is int *.
The type of &tp is int **.
The type of &tp[0] is int * because &tp[0] is equivalent to tp1) :
&tp[0] -> &(tp[0]) -> &(*(tp) + (0)) -> &(*tp) -> tp
Note : You do not need to use [0] with pointer to access the value of a scalar type, which the pointer is pointing at.
2. Which passing parameter we should use.
Its not clear, what exactly you want to ask.
You are passing value of tp to function() function which is nothing but &i. The ptr parameter of function() function will hold the &i when it is called. If you want to make changes to the value of i within the function() function then you can do it because ptr hold address of i and *ptr will give value at that address which is nothing but the value of variable i. If you just want to access the value of i, you can simply pass the value of variable i.
3. is this difference only for passing parameter?
Which difference? I believe, you mean - why there is difference in &tp and &ptr?
ptr is local variable of function() function and tp is local variable of main() function. Though, they both hold the address of variable i their own addresses are different because they are different variables.
1). C Standards#6.5.2.1
The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))..

Accepting a pointer address?

This is the source code
#include<stdio.h>
void main()
{
int *p,a=5;
p=&a;
scanf("%d",p);
printf("%d\t",*p);
printf("%d",a);
}
How can we accept an address of a pointer?.Cuz it has the address of variable 'a' already.There are no errors shown by the compiler.
Also,i'm not able to understand the output.
output:(if my input is 45)
45 45
Your pointer is also a variable like a and has it's own address. You can access it by saying &p. But you say scanf("%d", p); so it is accessing pointer's pointing address.
EDIT: if you want to print pointer's address you can use printf("%p\n",(void *) &p);
You can access pointer itself by its address &p
int pa;
int *p;
scanf("%d", &pa);
p = (int*) pa;
printf("%p\t", p); // printing pointer stored address (got from input)
printf("%d\n", (void *) *p); // printing value stored in address stored in p, of course would be segfault in case of invalid address
Also use it with caution, its unportable and may resulting undefined behavior. it may work on 32bit machines because of int and int* have same length of bits but for other CPU's may not work.

Print value and address of pointer defined in function?

I think this is a really easy thing to code, but I'm having trouble with the syntax in C, I've just programmed in C++.
#include <stdio.h>
#include <stdlib.h>
void pointerFuncA(int* iptr){
/*Print the value pointed to by iptr*/
printf("Value: %x\n", &iptr );
/*Print the address pointed to by iptr*/
/*Print the address of iptr itself*/
}
int main(){
void pointerFuncA(int* iptr);
return 0;
}
Obviously this code is just a skeleton but I'm wondering how I can get the communication between the function and the main working, and the syntax for printing the address pointed to and of iptr itself? Since the function is void, how can I send all three values to main?
I think the address is something like:
printf("Address of iptr variable: %x\n", &iptr );
I know it's a simple question, but all the examples I found online just got the value, but it was defined in main as something like
int iptr = 0;
Would I need to create some arbitrary value?
Thanks!
Read the comments
#include <stdio.h>
#include <stdlib.h>
void pointerFuncA(int* iptr){
/*Print the value pointed to by iptr*/
printf("Value: %d\n", *iptr );
/*Print the address pointed to by iptr*/
printf("Value: %p\n", iptr );
/*Print the address of iptr itself*/
printf("Value: %p\n", &iptr );
}
int main(){
int i = 1234; //Create a variable to get the address of
int* foo = &i; //Get the address of the variable named i and pass it to the integer pointer named foo
pointerFuncA(foo); //Pass foo to the function. See I removed void here because we are not declaring a function, but calling it.
return 0;
}
Output:
Value: 1234
Value: 0xffe2ac6c
Value: 0xffe2ac44
To access the value that a pointer points to, you have to use the indirection operator *.
To print the pointer itself, just access the pointer variable with no operator.
And to get the address of the pointer variable, use the & operator.
void pointerFuncA(int* iptr){
/*Print the value pointed to by iptr*/
printf("Value: %x\n", *iptr );
/*Print the address pointed to by iptr*/
printf("Address of value: %p\n", (void*)iptr);
/*Print the address of iptr itself*/
printf("Address of iptr: %p\n", (void*)&iptr);
}
The %p format operator requires the corresponding argument to be void*, so it's necessary to cast the pointers to this type.
Address are some memory values which are written in hexadecimal notation starting with 0x
/Value pointed to by the pointer iptr/
printf("Value is: %i", *iptr);
Address pointed to by the pointer will be the value of the iptr pointer itself
/print the address pointed to by the iptr/
printf("Address is: %p", iprt);
/print the address of iptr itself/
printf("Address of iptr: %p", &iptr )
int* iptr is already a pointer, so you don't need the & in front of it when you write
printf("Address of iptr variable: %x\n", &iptr );
This is how to print a pointer value.
printf("Address of iptr variable: %p\n", (void*)iptr);
Also you have the function prototype for pointerFuncA() in the wrong place, being inside main(). It should be outside of any function, before it is called.
#include <stdio.h>
#include <stdlib.h>
void pointerFuncA(int* iptr){
/*Print the value pointed to by iptr*/
printf("Value: %p\n", (void*) iptr );
/*Print the address pointed to by iptr*/
/*Print the address of iptr itself*/
}
int main(){
int iptr = 0;
pointerFuncA( &iptr);
return 0;
}
I think you are looking at something like this, there is no need to re-define the function again in the main....

Dereference the name of a two dimension is same as the name. So what does dereference do?

What does dereference do?
Does it just return the value of the address in pointer.
WIKI says " It operates on a pointer variable, and returns an l-value equivalent to the value at the pointer address "
I got confused by the code below:
int p[2][2] = {1, 2, 3, 4};
printf("%p\t%p", p, *p);
I know that p is a pointer points to an array, like this
int (*p)[2];
Say p has the address of 0x003DEF4C. So *p doesn't should be the value in 0x003DEF4C ?
But it has the same value with p.
So it likes that dereference not just return the value of the address that the pointer points to.
What does dereference do? Does it just return the value of the address in pointer?
When you dereference a pointer, you get the value of what the pointer points to.
Say p has the address of 0x003DEF4C. So *p doesn't should be the value in 0x003DEF4C ? But it has the same value with p.
This is true for the particular code you have. Take a look something a little different from yours.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int p1[2][2] = {1, 2, 3, 4};
int* p2[2] = {NULL, NULL};
int** p3 = NULL;
int** p4 = NULL;
p2[0] = (int*)malloc(2*sizeof(int));
p2[1] = (int*)malloc(2*sizeof(int));
p2[0][0] = 1;
p2[0][1] = 2;
p2[1][0] = 3;
p2[1][1] = 4;
p3 = (int**)malloc(2*sizeof(int*));
p3[0] = (int*)malloc(2*sizeof(int));
p3[1] = (int*)malloc(2*sizeof(int));
p3[0][0] = 1;
p3[0][1] = 2;
p3[1][0] = 3;
p3[1][1] = 4;
p4 = (int**)malloc(4*sizeof(int));
p4[0] = (int*)p4;
p4[1] = p4[0]+2;
p3[0][0] = 1;
p3[0][1] = 2;
p3[1][0] = 3;
p3[1][1] = 4;
printf("Address of p1: %p\n", (void*)p1);
printf("Address of p1[0]: %p\n", (void*)p1[0]);
printf("Address of p1[1]: %p\n", (void*)p1[1]);
printf("\n");
printf("Address of p2: %p\n", (void*)p2);
printf("Address of p2[0]: %p\n", (void*)p2[0]);
printf("Address of p2[1]: %p\n", (void*)p2[1]);
printf("\n");
printf("Address of p3: %p\n", (void*)p3);
printf("Address of p3[0]: %p\n", (void*)p3[0]);
printf("Address of p3[1]: %p\n", (void*)p3[1]);
printf("\n");
printf("Address of p4: %p\n", (void*)p4);
printf("Address of p4[0]: %p\n", (void*)p4[0]);
printf("Address of p4[1]: %p\n", (void*)p4[1]);
printf("\n");
/* Add code to free the allocated memory */
}
p1 and everything it defines are created using memory on the stack. The address that p1 points to is equal to address that p1[0] points to. They both point to an address in the stack.
p2, p2[0], and p2[1] are created using memory on stack. p2 points to an address in the stack memory. However memory allocated for p2[0] and p2[1] are from the heap. p2 points to an address that is different from the address p2[0] points to.
p3 is created on the stack but the address it points to are created from the heap. The address p3[0] points to is also created from the heap. Since they were created using separate calls to malloc, they point to different addresses.
p4 is an example of how you can manipulate contiguous memory allocated from the heap to suit your own needs. Since we know we need to store 4 integers, we can allocate memory for them and make sure our pointers point to the right places. Manipulation of the heap memory for p4 is analogous to what the compiler does when we create everything on the stack.
Here's a sample output when I run the program:
./test-22
Address of p1: 0x28ac18
Address of p1[0]: 0x28ac18
Address of p1[1]: 0x28ac20
Address of p2: 0x28ac10
Address of p2[0]: 0x80010458
Address of p2[1]: 0x80010468
Address of p3: 0x80010478
Address of p3[0]: 0x80010488
Address of p3[1]: 0x80010498
Address of p4: 0x800104a8
Address of p4[0]: 0x800104a8
Address of p4[1]: 0x800104b0
What wiki says is true and very simple. Start with one dimension array
int p[4] = {1, 2, 3, 4};
printf("%p\t%d", (void *)p, *p);
p converts to the pointer to first element of array p[]. Dereferencing p will return the value stored at the address p points to. *p is an l-value which is equivalent to the variable p[0].
Take example of simple assignments;
p[0] = 5; // In this assignment p[0] is a l-value
*p = p[0] + 1; // p[0] is r-value and *p is l-value
p[0] = *p - 5; // p[0] is l-value and *p is r-value
In your printf you are asking to:
p: the address of your 2 dimensional array = address of the 1st element of the array
*p: the address of the 1 dimensional sub-array = address of the 1st element of the array (which is the same address than above)
Note that if you look at the address of (*p)[1] for example (the 2nd sub-array) you should have something different.

Resources