In the book it explains:
ptr = &a /* set ptr to point to a */
*ptr = a /* '*' on left:set what ptr points to */
They seem the same to me, aren't they?
No. The first one changes the pointer (it now points at a). The second one changes the thing that the pointer is pointing at.
Consider:
int a = 5;
int b = 6;
int *ptr = &b;
if (first_version) {
ptr = &a;
// The value of a and b haven't changed.
// ptr now points at a instead of b
}
else {
*ptr = a;
// The value of b is now 5
// ptr still points at b
}
Well, no. But to explain the similar behaviour, Adding to Oli Charlesworth's answer:
Consider:
int a = 5;
int* ptr = new int;
if(first_version) {
ptr = &a;
//ptr points to 5 (using a accesses the same memory location)
} else {
*ptr = a;
//ptr points to 5 at a different memory location
//if you change a now, *ptr does not change
}
edit: sorry for using new (c++ not c) but the pointer thing does not change.
No, in ptr = &a you are storing the address of variable 'a' in variable 'ptr'
i.e., something like ptr=0xef1f23.
in *ptr = a you are storing the value of variable 'a' in pointer variable '*ptr'
i.e., something like *ptr=5.
Both are not same.
If u modify the value of a = 10. Then print again *ptr. It will print only 5. not 10.
*ptr = a; //Just copies the value of a to the location where ptr is pointing.
ptr = &a; //Making the ptr to point the a
*ptr=&a C++ compiler will genrate error becoz u r going to assign addres to adres
ptr=&a,this is true here ptr working like variable and &a is a addres of a which contain some value
check and try
int *ptr,a=10;
ptr=&a;output=10;
*ptr=&a signifies that our pointer is pointing towards address of the variable a
while
*ptr=a signifies that our pointer is pointing towards value a
*ptr = &a is not technically correct.
int *ptr = &a; is correct ..... Way (i)
(or)
int *ptr;
ptr = &a; is correct ..........Way (ii)
Here *ptr is a pointer to integer datatype.
int *ptr;
*ptr = a; This means ptr becomes a NULL pointer [i.e. it does not point to any memory location]. *ptr holds the value of a.
Related
Suppose *ptr points to a variable. What does *ptr, &ptr, and ptr each mean?
Many times, I get confused between them. Do anyone mind clarifying between those statements and give some concrete examples?
Take the following variables in a function.
int i = 0;
int* ptr = &i;
In the function, the memory layout could look something like:
Memory corresponding to i:
+---+---+---+---+
| 0 |
+---+---+---+---+
^
|
Address of i
Memory corresponding to ptr:
+---+---+---+---+
| address of i |
+---+---+---+---+
^
|
Address of ptr
In the above scenario,
*ptr == i == 0
ptr == address of i == address of memory location where the vale of i is stored
&ptr == address of ptr == address of memory location where the value of ptr is stored.
Hope that makes sense.
Here is a computer memory:
int i = 1023
If I want to print i, then I just have to do:
printf(..., i);
// out: 1023
If I want to print where i lives, then I just have to do:
printf(..., &i);
// out: 0x4
But let's say I want to remember where i lives:
int *i_ptr = &i; // i_ptr is a variable of type int *
Then I can print it this way:
printf(..., i_ptr);
// out: 0x04
But if just print out the value of i, I need a *:
printf(..., *i_ptr); // * also doubles as a way to follow the pointer
// out: 1023
Or I can just print out where i_ptr lives:
printf(..., &i_ptr);
// out: 0x32
Given the declarations
int i = 0x01234567;
int *ptr = &i;
the following are true:
Expression Type Value
---------- ---- -----
ptr int * Address of i
*ptr int Value stored in i (0x01234567)
&ptr int ** Address of ptr variable
In memory, it would look something like the following (assuming 32-bit int)
Item Address 0x01 0x02 0x03 0x04
---- ------- ---- ---- ---- ----
i 0x7fffbb00 0x01 0x23 0x45 0x67
ptr 0x7fffbb04 0x7f 0xff 0xbb 0x00
So the value of ptr is 0x7fffbb00, the value of &ptr is 0x7fffbb04, and the value of *ptr is 0x01234567.
Let's suppose you have:
int number = 5;
int *ptr = &number;
ptr will be the variable, of type int *, instead storing a 5 or
"foo", it will store an address like 0xf0f0f004 or whatever it is the
address of the variable number.
*ptr will be the value of what it is in this address of memory 0xf0f0f004, in this specific case is 5.
&ptr will be the address where it is located the variable that will
be in other place for example 0xff00ffaa or whatever.
ptr and number are located in different places in memory, both stores values, one just store a number and the other store an address. And the language allows you putting *, access the value of this address.
If *ptr points to a variable, then that would mean that *ptr is a pointer itself. That would mean you're declaring ptr as follows: int **ptr;
In this case:
ptr is a pointer to the pointer to your variable
*ptr is the pointer to your variable
&ptr gives you the address of ptr, so a pointer to the pointer to the pointer to your variable
For example:
//set up work
int x;
int *intermediatePtr;
int **ptr;
x = 5;
intermediatePtr = &x; //used only for additional level of indirection in this example
ptr = &intermediatePtr; //ie *ptr = &x;
//should print out the memory address for the pointer to the address of x
printf("%d", ptr);
//should print out the memory address of x (different memory location than above)
printf("%d", *ptr);
//should print out the memory address of the variable
//which holds the memory address of x
//(again, different memory location than both above examples)
printf("%d", &ptr);
If ptr points to a variable instead of *ptr (ie int *ptr; ptr = &x;), there is one less level of indirection than my above example.
int *ptr; // declares a pointer to integer.
int val; // declares an integer.
&val; // pointer to val
ptr = &val; // ptr will now point to val
*ptr = 5; // same as writing val = 5
ptr++; // pointer to the next int after val (in this case, it will be undefined behaviour, it is useful if this pointer pointed to a cell in an array)
int arr[10]; // declares an array of size 10
ptr = arr; // ptr now points to arr[0] (name of an array can be implicity cast to pointer to first element)
ptr++; // ptr now points to arr[1]
& = Reference
* = De reference
ptr is the identifier/name. You declare it by int *ptr.
Here is a small C program:
#include<stdio.h>
int main()
{
int *ptr,ref;
ptr= &ref;
ref=12;
printf("%d\n",*ptr );
}
In C,int *ptr is an integer pointer. You can use other data types like float, char etc,.
ptr = &ref gets the address of ref and stores in ptr. Since we declared ptr as integer pointer, when we print the value pointed, we have to De-reference it by using *.
I am little confused and tried finding explanation but all "difference" questions asked are about type *name vs type* name which i know answer of.
I have code like this:
int a = 1;
printf("a = %d", a); // Prints 1
int *pt = a;
printf("pt = %d", pt); // Prints 1
*pt = 2; // Crash why? What am i pointing to here?
&pt = 2; // Not even compiling since
pt = 2; // Works
printf("pt = %d\n", pt); // Prints 2
printf("a = %d\n", a); // Prints 1
I know in order to change value of a i should have done int *pt = &a and then *pt = 2 and that is not my question.
My question is in this case, is using int *pt = a same as using int pt = a or is there any advantage of using it as pointer?
int a = 1;
...
int *pt = a;
Attempts to store the value 1 as the address held by pointer pt. Any dereference of pt is guaranteed to SegFault as address 1 is well down at the bottom of the system-reserved memory range -- which you have no ability to access, resulting in an access violation and SegFault.
What Is A Pointer?
A pointer is simply a normal variable that holds the address of something else as its value. In other words, a pointer points to the address where something else can be found. Where you normally think of a variable holding an immediate values, such as int a = 5;, a pointer would simply hold the address where 5 is stored in memory, e.g. int *b = &a;. It works the same way regardless what type of object the pointer points to. It is able to work that way because the type of the pointer controls the pointer arithmetic, e.g. with a char * pointer, pointer+1 point to the next byte, for an int * pointer (normal 4-byte integer), pointer+1 will point to the next int at an offset 4-bytes after pointer. (so a pointer, is just a pointer.... where arithmetic is automatically handled by the type)
So in your case:
int a = 1;
...
int *pt = &a;
Will assign the address where a is stored in memory to the pointer variable pt. You may then access the value at that address by dereferencing pt (e.g. *pt)
What you are doing is setting the address to which the pointer pt points to, to what a is currently holding (1 in your case). Since *a is most definitely not a valid and accessible address you will most likely get a segmentation fault when trying to dereference it. This is somewhat the same as if you are creating a null pointer by int *pt = 0 but instead of 0 you use whatever is in a.
Keep in mind that there is probably something funky going on with converting a signed int to an address which only makes the whole thing even worse.
I try use a pointer to a constant integer number in C:
void *p = NULL;
p = (int *) 1;
printf("p=%d\n", *(int *)p);
but I got a segment fault.....
I cannot figure out how a pointer to a constant number in C w/o declaring a variable.
You are not taking the pointer to a constant but you are converting the constant to a pointer. You should do something like:
const int one = 1;
const int *p;
p = &one;
You cannot however do something like:
p = &1;
since literal constants haven't a memory location.
*(int *)p
You are derefrencing p, which is a pointer that has a value of 1. It's unlikely to be a valid address, segmentation fault is not a surprise.
P.S: p is not a pointer to const integer, it has a value of a constant integer.
p = (int *) 1; does not set the pointer p to point to a memory location with value 1. This sets the value of the pointer to 1, i.e, sets the pointer to point to the memory location with address 1.
try this:
void *p = NULL;
const int num = 1;
p = (int*)(&num);
printf("p=%d\n", *((int *)p));
Suppose *ptr points to a variable. What does *ptr, &ptr, and ptr each mean?
Many times, I get confused between them. Do anyone mind clarifying between those statements and give some concrete examples?
Take the following variables in a function.
int i = 0;
int* ptr = &i;
In the function, the memory layout could look something like:
Memory corresponding to i:
+---+---+---+---+
| 0 |
+---+---+---+---+
^
|
Address of i
Memory corresponding to ptr:
+---+---+---+---+
| address of i |
+---+---+---+---+
^
|
Address of ptr
In the above scenario,
*ptr == i == 0
ptr == address of i == address of memory location where the vale of i is stored
&ptr == address of ptr == address of memory location where the value of ptr is stored.
Hope that makes sense.
Here is a computer memory:
int i = 1023
If I want to print i, then I just have to do:
printf(..., i);
// out: 1023
If I want to print where i lives, then I just have to do:
printf(..., &i);
// out: 0x4
But let's say I want to remember where i lives:
int *i_ptr = &i; // i_ptr is a variable of type int *
Then I can print it this way:
printf(..., i_ptr);
// out: 0x04
But if just print out the value of i, I need a *:
printf(..., *i_ptr); // * also doubles as a way to follow the pointer
// out: 1023
Or I can just print out where i_ptr lives:
printf(..., &i_ptr);
// out: 0x32
Given the declarations
int i = 0x01234567;
int *ptr = &i;
the following are true:
Expression Type Value
---------- ---- -----
ptr int * Address of i
*ptr int Value stored in i (0x01234567)
&ptr int ** Address of ptr variable
In memory, it would look something like the following (assuming 32-bit int)
Item Address 0x01 0x02 0x03 0x04
---- ------- ---- ---- ---- ----
i 0x7fffbb00 0x01 0x23 0x45 0x67
ptr 0x7fffbb04 0x7f 0xff 0xbb 0x00
So the value of ptr is 0x7fffbb00, the value of &ptr is 0x7fffbb04, and the value of *ptr is 0x01234567.
Let's suppose you have:
int number = 5;
int *ptr = &number;
ptr will be the variable, of type int *, instead storing a 5 or
"foo", it will store an address like 0xf0f0f004 or whatever it is the
address of the variable number.
*ptr will be the value of what it is in this address of memory 0xf0f0f004, in this specific case is 5.
&ptr will be the address where it is located the variable that will
be in other place for example 0xff00ffaa or whatever.
ptr and number are located in different places in memory, both stores values, one just store a number and the other store an address. And the language allows you putting *, access the value of this address.
If *ptr points to a variable, then that would mean that *ptr is a pointer itself. That would mean you're declaring ptr as follows: int **ptr;
In this case:
ptr is a pointer to the pointer to your variable
*ptr is the pointer to your variable
&ptr gives you the address of ptr, so a pointer to the pointer to the pointer to your variable
For example:
//set up work
int x;
int *intermediatePtr;
int **ptr;
x = 5;
intermediatePtr = &x; //used only for additional level of indirection in this example
ptr = &intermediatePtr; //ie *ptr = &x;
//should print out the memory address for the pointer to the address of x
printf("%d", ptr);
//should print out the memory address of x (different memory location than above)
printf("%d", *ptr);
//should print out the memory address of the variable
//which holds the memory address of x
//(again, different memory location than both above examples)
printf("%d", &ptr);
If ptr points to a variable instead of *ptr (ie int *ptr; ptr = &x;), there is one less level of indirection than my above example.
int *ptr; // declares a pointer to integer.
int val; // declares an integer.
&val; // pointer to val
ptr = &val; // ptr will now point to val
*ptr = 5; // same as writing val = 5
ptr++; // pointer to the next int after val (in this case, it will be undefined behaviour, it is useful if this pointer pointed to a cell in an array)
int arr[10]; // declares an array of size 10
ptr = arr; // ptr now points to arr[0] (name of an array can be implicity cast to pointer to first element)
ptr++; // ptr now points to arr[1]
& = Reference
* = De reference
ptr is the identifier/name. You declare it by int *ptr.
Here is a small C program:
#include<stdio.h>
int main()
{
int *ptr,ref;
ptr= &ref;
ref=12;
printf("%d\n",*ptr );
}
In C,int *ptr is an integer pointer. You can use other data types like float, char etc,.
ptr = &ref gets the address of ref and stores in ptr. Since we declared ptr as integer pointer, when we print the value pointed, we have to De-reference it by using *.
I am a total beginner to C so please, work with my ignorance. Why does a normal pointer
int* ptr = &a; has two spaces in memory (one for the pointer variable and one for the value it points to) and an array pointer int a[] = {5}; only has one memory space (if I print out
printf("\n%p\n", a) I get the same address as if I printed out: printf("\n%p\n", &a).
The question is, shouldn't there be a memory space for the pointer variable a and one for its value which points to the first array element? It does it with the regular pointer int* ptr = &a;
It's a little unclear from your question (and assuming no compiler optimization), but if you first declare a variable and then a pointer to that variable,
int a = 4;
int *p = &a;
then you have two different variables, it makes sense that there are two memory slots. You might change p to point to something else, and still want to refer to a later
int a = 4;
int b = 5;
int *p = &a; // p points to a
// ...
p = &b; // now p points to b
a = 6; // but you can still use a
The array declaration just allocates memory on the stack. If you wanted to do the same with a pointer, on the heap, you would use something like malloc or calloc (or new in c++)
int *p = (int*)malloc(1 * sizeof(int));
*p = 4;
but of course remember to free it later (delete in c++)
free(p);
p = 0;
The main misunderstanding here is that &a return not pointer to pointer as it expected that's because in C language there some difference between [] and * (Explanation here: Difference between [] and *)
If you try to &a if a was an pointer (e.g. int *a) then you obtain a new memory place but when your use a static array (i.e. int a[]) then it return address of the first array element. I'll also try to clarify this by mean of the next code block.
#include <stdio.h>
int main(int argc, char *argv[])
{
// for cycles
int k;
printf("That is a pointer case:\n");
// Allocate memory for 4 bytes (one int is four bytes on x86 platform,
// can be differ for microcontroller e.g.)
int c = 0xDEADBEEF;
unsigned char *b = (unsigned char*) &c;
printf("Value c: %p\n", c);
printf("Pointer to c: %p\n", &c);
printf("Pointer b (eq. to c): %p\n", b);
// Reverse order (little-endian in case of x86)
for (k = 0; k < 4; k++)
printf("b[%d] = 0x%02X\n", k, b[k]);
// MAIN DIFFERENCE HERE: (see below)
unsigned char **p_b = &b;
// And now if we use & one more we obtain pointer to the pointer
// 0xDEADBEEF <-- b <-- &p_b
// This pointer different then b itself
printf("Pointer to the pointer b: %p\n", p_b);
printf("\nOther case, now we use array that defined by []:\n");
int a[] = {5,1};
int *ptr = &a;
// 'a' is array but physically it also pointer to location
// logically it's treat differ other then real pointer
printf("'a' is array: %x\n", a);
// MAIN DIFFERENCE HERE: we obtain not a pointer to pointer
printf("Pointer to 'a' result also 'a'%x\n", &a);
printf("Same as 'a': %x\n", ptr);
printf("Access to memory that 'a' pointes to: \n%x\n", *a);
return 0;
}
This is very simple. In first case,
int* ptr = &a;
you have one variable a already declared and hence present in memory. Now you declare another variable ptr (to hold the address, in C variables which hold address of another variable are called pointers), which again requires memory in the same way as a required.
In second case,
int a[] = {5};
You just declare one variable (which will hold a collection of ints), hence memory is allocated accordingly for a[].
In this expression, int* p = &a; p has only one memory location, of the WORD size of your CPU, most probably, and it is to store the address (memory location) of another variable.
When you do *p you are dereferencing p, which means you are getting the value of what p points to. In this particular case that would be the value of a. a has its own location in memory, and p only points to it, but does not itself store as content.
When you have an array, like int a[] = {5};, you have a series (or one) of memory locations, and they are filled with values. These are actual locations.
Arrays in C can decay to a pointer, so when you printf like you did with your array, you get the same address, whether you do a or &a. This is because of array to pointer decay.
a is still the same location, and is only that location. &a actually returns a pointer to a, but that pointer sits else where in memory. If you did int* b = &a; then b here would not have the same location as a, however, it would point to a.
ptr is a variable containing a memory address. You can assign various memory addresses to ptr. a is a constant representing a fixed memory address of the first element of the array. As such you can do:
ptr = a;
but not
a = ptr;
Pointers point to an area in memory. Pointers to int point to an area large enough to hold a value of int type.
If you have an array of int and make a pointer point to the array first element
int array[42];
int *p = array;
the pointer still points to a space wide enough for an int.
On the other hand, if you make a different pointer point to the whole array, this new pointer points to a larger area that starts at the same address
int (*q)[42]; // q is a pointer to an array of 42 ints
q = &array;
the address of both p and q is the same, but they point to differently sized areas.