Why Pointer is not incrementing? - c

Consider the following code
#include<stdio.h>
int main()
{
int a[5];
int *ptr=a;
printf("\n%u", &ptr);
++ptr;
printf("\n%u", &ptr);
}
On Output I'm getting same address value, Why pointer address is not incrementing.

The pointer is being incremented. The problem is that you are looking at the address of the pointer itself. The address of a variable cannot change. You mean to look at the value of the pointer, that is, the address it stores:
printf("\n%p", ptr);

On Output I'm getting same address value, Why pointer address is not incrementing.
The value of ptr is different from address of ptr.
By using ++ptr;, you are changing the value of ptr. That does not change the address of ptr. Once a variable is created, its address cannot be changed at all.
An analogy:
int i = 10;
int *ip = &ip;
++i; // This changes the value of i, not the address of i.
// The value of ip, which is the address of i, remains
// same no matter what you do to the value of i.

Let's go through the basics.
When you declare a pointer variable, you use a * with the type of whatever is being pointed to.
When you dereference a pointer (take the value this pointer is pointing to), you put * before it.
When you get the address of something (an address which can be stored in a pointer variable), you put & before whatever you're trying to get the address of.
Let's go through your code.
int *ptr=a; - ptr is a pointer-to-int, pointing to the first element of a.
printf("\n%u", &ptr); this prints the address of ptr. As ptr is a pointer, &ptr is a pointer-to-pointer. That is not what you wanted to see (as I understand), and you'd need to remove &.
++ptr; you inscrease the value of ptr, which is all right, but
printf("\n%u", &ptr); will still output the same thing, because although the contents of the pointer ptr have changed, its address has not.
So, you just need to replace each of the printf calls with printf("\n%u", ptr); to get the desired results.

Related

What is the address of a pointer in C?

int main()
{
int *p;
printf("%p \n", &p);
printf("%p \n", p);
return 0;
}
By executing this code I am receiving the following output:
0x16b77f710
0x104683f4c
I expected to get the same memory address, because the &p id not referenced to any other variable.
Why i am getting two different memory address?
Thanks,
The pointer is a normal object having (in your case type of int *). It cant point to itself because the type of such pointer would have to be int **
*image stolen from internet.
A pointer is a variable like any other. It has an address, which is typically the address in memory where that variable sits.
Like any other variable, a pointer variable also has some data in it. For a pointer variable, that data is the address of some other variable, the variable at which the pointer points.
The address of a variable, and the contents of a variable, are two totally different things. They are almost never equal.
Try this program, in which I give your variable p something to point to:
int main()
{
int i = 5;
int *p = &i;
printf("p: %p, p's address: %p\n", p, &p);
printf("i: %d, i's address: %p\n", i, &i);
}
You should notice two things:
As in your first program, "p" and "p's address" will be different.
Whatever value you see for "p", it will be the same as "i's address".
The reason is that a pointer, when declared, does not point to itself by default. Simplified you can imagine it in such a way that a pointer occupies 2 memory cells. 1 memory cell has the virtual address where the pointer itself is located (&p in your case), the 2nd memory cell contains the virtual address where the pointer points to (p in your case).
Since memory cells retain their value when they are deallocated, the cell containing the destination address of your pointer still contains an obsolete value from another, already completed process.
You would have the same phenomenon if you declare a new integer variable and then print its value with printf, you will see that there will already be some number in the new variable that will appear completely random. This is also due to the fact that there is still an obsolete value in the corresponding memory cell.
Let assume there is random memory block for just understanding name it a. Now assume that p is pointing to that memory block.
&p returns the address of memory block where p is present.
p returns the address of memory block(&a) to the variable/memory block(a) which p is pointing.
So of course it will give different memory addresses.
I expected to get the same memory address, because the &p id not referenced to any other variable.
Pointer variables do not automatically point to themselves; if you don't explicitly initialize them, then their initial value will be indeterminate (or NULL, depending on how they are declared).
There's nothing magic about pointer variables - like any other scalar, they store some kind of value; it's just that in their case, that value is an address of another object.
If you really want p to store its own address, you'll have to do something like
p = (int *) &p;
The cast is necessary because the type of the expression &p is int **, and you can't assign a pointer value of one type to a variable of a different pointer type. But, pointers to different types are not guaranteed to have the same size, representation, or alignment. On modern commodity hardware like x86 you can probably count on int * and int ** having the same size and representation, just be aware that doesn't have to be the case everywhere.

passing a pointer address vs pointer to a pointer in C

I'm slightly confused between these two pieces of code:
version 1: (gives warnings after compiling)
int func(int *ptr2)
{
*ptr2 += 1;
}
int main()
{
int a = 5;
int *ptr = &a;
printf("Address of a: %x\n", a);
printf("Before: %x\n", ptr);
func(&ptr);
printf("After: %x\n", ptr);
return 0;
}
Output:
Address of a: 5770a18c
Before: 5770a18c
After: 5770a18d
version 2:
int func(int **ptr2)
{
*ptr2 += 1;
}
int main()
{
int a = 5;
int *ptr = &a;
printf("address of a: %x\n", &a);
printf("Before: %x\n", ptr);
func(&ptr);
printf("After: %x\n", ptr);
return 0;
}
Output:
Address of a: cc29385c
Before: cc29385c
After: cc293860
If I'm understanding pointers in C correctly when we pass by reference, we are creating a pointer to that location. This allows us to change the value at the address held by the pointer through the dereference operator.
However, if we want to change the value held by a pointer, we use a pointer to a pointer. We pass the address of the pointer and create a new pointer to hold said address. If we want to change the value, we use the dereference operator to access our pointer's (defined elsewhere) value.
Hopefully I'm on the right track, but I'm struggling to visualize what's happening with version 1 specifically. Mainly, I'd just like to understand the difference in make-up and output between these two programs. I assume version 1 is still a pointer to a pointer, but why are the incremented values different between both programs? If version 1 is successfully incrementing ptr's value (which I suspect is not), why is that I cannot find code with the same syntax? I think I'm missing something fairly trivial here... Any help is appreciated
Based on your output, you appear to be compiling for a 32-bit system where addresses and int are of that size.
When you increment the value at *ptr with that type being int, it will simply add 1.
When *ptr resolves to an int* then it will increment by sizeof(int) because the value at the current address in this case is 4 bytes long, so we have to increase the address by the number of bytes that an int consumes so that we're pointing at the next int. Note that doing this is only valid if you actually have allocated memory at the subsequent address.
Generally you pass a T** when the callee needs to modify the address to point to - such as say, the callee performs a malloc() to allocate space for the pointer.
&ptr is a pointer to a pointer, but what is passed to func() is a pointer to int converted from &ptr in implementation-defined manner. Then, *ptr2 += 1; is incrementing int and add 1 to what is pointed by ptr2 (the pointer ptr in main(), which eventually have the same reepresentation as `int in your system).
In version 2, the pointer to a pointer is correctly passed to func(). Therefore, pointer aritimetic is performed and the size of int is added to the address.
Note that you invoked undefined behavior by passing data having wrong type to printf(). The correct way to print pointers is like this:
printf("Before: %p\n", (void*)ptr);
As you see, cast the pointer to void* and use %p specifier.

Pointers in C(Value of a pointer)?

C Language:
If (p) is a pointer declared as follows:
int a=5, *p;
p = &a;
What does *p will print?
*p won't "print" anything; that's just an expression that de-references the pointer, and produces whatever int value it points at.
You can print it with:
printf("*p=%d\n", *p);
and it will print 5 in your program since p points at a, and the value of a is 5.
The %d is important, it tells printf() to expect an int value, and to format that into a string for printing.
You can also print the pointer itself:
printf("p is %p, a is at %p\n", p, (void *) &a);
this will print the same address twice. The %p format specifier is used for printing addresses.
p is a pointer pointing to an int, *p will be the value of the variable. In this case a. Just for simplicity, you can think of & as the address of, * as the content of pointer as this post The 5-minute Guide to C Pointers points out.
remember a and p are only names, they stands for a variable. Assume the address of a is 1024(which is hardly the real case). Their relation is illustrated as below. The value of a is 5 , When we use p = &a, we assign the address of a, which is 1024 to p. *p will retrieves the value of the address p pointer to, which is what you're looking for: 5.
pic http://cizixs.u.qiniudn.com/pointer
If you want to print the vale, #unwind gives the answer.
Here is a tutorial that might clarify c pointer for you.
p is a pointer to an int. That means it can point to an address, in which an int will be stored.
Writing
p = &a
you set the pointer to point in the address in which integer a is stored.
When you try to print *p, you will get the value that is stored in the address that pointer p points. So you will get 5.
Keep in mind that operator & returns the address of a variable. So &a will return the address of the variable a . Also, when you want to get the value of the variable that is stored in address, if you have a pointer who points ins this address, you use the dereference operator, *. Hence, *p returns the value that is stored in the address that p points to.
p = &a;
p is pointer to a. i.e p holds address of a. and
*p
will give value of a. as & is used to get the address of a variable, * is used for dereferencing a pointer i.e. to get the value of the variable to which the pointer points.

Dynamic allocation and pointers

int *ptr;
ptr=(int *)malloc(sizeof(int)*2);
ptr=100; /*What will happen if I put an asterisk(*) indicating *ptr=100? */
ptr++;
printf("ptr=%d",*ptr);
free(ptr);
So, I wanted the pointer to increment. I allocated a size of 4(2*2) for the pointer. But I couldn't understand how the pointer increments only by 2. And if I put an asterisk int the 3rd line,that is *ptr=100; It shows something else.
If you have int * ptr, then ptr++ increments the pointer by the size of a single int. If int is two bytes on your platform, that's why it increments by two.
*ptr = 100 would store the value 100 at the int pointed to by ptr, i.e. the first of the two ints that you allocated with your malloc() call.
ptr = 100 will attempt to assign the memory address 100 to ptr, which is almost certainly not what you want, as you would lose your reference to the memory you just malloc()ed, and what is at memory location 100 is probably not meaningful for you or accessible to you.
As it currently stands, if you were to do *ptr = 100 and then ptr++, your printf() call would result in undefined behavior since you'd have incremented the pointer to point to uninitialized memory (i.e. the second of the two ints you allocated with your malloc() call), whose contents you then attempt to output.
(*ptr)++ on the other hand would increment that 100 value to 101, leave the value of ptr unchanged, your printf() call would be fine, and output 101. The second of the two ints you allocate would still remain uninitialized, but that's no problem if you don't attempt to access it.
Also, don't cast the return from malloc(), ptr=(int *)malloc(sizeof(int)*2) should be ptr=malloc(sizeof(int)*2), or even better, ptr = malloc(sizeof(*ptr) * 2);
Try this:
int *ptr;
ptr = malloc(2 * sizeof *ptr);
printf("ptr = %p.\n", (void *) ptr); // Examine pointer before increment.
ptr++;
printf("ptr = %p.\n", (void *) ptr); // Examine pointer after increment.
You will see that the value of ptr is incremented by the number of bytes in an int. The C language automatically does pointer arithmetic in units of the pointed-to element. So a single increment of an int pointer in C becomes, at the machine level, an increment of the number of bytes of an int.
Notes
%p is the proper specifier to use when printing a pointer, not %d. Also, the pointer must be cast to void * or const void *.
ptr = malloc(2 * sizeof *ptr); is a cleaner way to allocate memory and assign a pointer than your original code, because:
Using sizeof *ptr causes the code to automatically adapt if you ever change the type of ptr. Instead of having to change the type in two places (where ptr is declared and where malloc is called), one change suffices. This reduces opportunities for errors.
malloc does not need to be cast to the destination type. It returns a void *, which C will automatically convert to the destination type of the assignment without complaint. (C++ is different.) It will still work if you cast it, but this can mask another problem: If you accidentally do not declare malloc (as by failing to include <stdlib.h>, and compile in an old version of C, malloc will be implicitly declared to return an int, and the cast will mask the error. Leaving the expression without a cast will cause a warning message to be produced when this happens.
This line changes value of address in pointer to some nonsense (100 will not be any valid address):
ptr=100;
Then you increment the pointer to 100 + sizeof(int) because the pointer has type of int* which automatically increments address by amount of bytes to get to the next integer that ptr points to.
At next line you dereference the invalid pointer so your code should crash, but the command is ok if your pointer had valid address:
printf("ptr=%d",*ptr);
To repair your code just don't change the pointer itself but change the data:
int *ptr;
ptr=(int *)malloc(sizeof(int)*2);
*ptr=123; /*What will happen if I put an asterisk(*) indicating *ptr=100? */
printf("ptr=%d",*ptr);
ptr++;
*ptr=234;
printf("ptr+1=%d",*ptr);
// you can set or get your data also this way:
ptr[0] = 333;
ptr[1] = 444;
printf("ptr[0]=%d",ptr[0]);
printf("ptr[1]=%d",ptr[1]);
free(ptr);
First thing you need to understand is a POINTER points to ADDRESS, when your assign 100 to ptr, it means your pointer ptr now points to memory location whose address is 100.
Secondly pointer arithmetic depends on type of pointer, in your case ptr is a pointer pointing to integer. SO when you increment ptr, it means it will jump to the memory location of next integer. So, ptr gets incremented by 2 (memory occupied by one int on your platform)
To be simple
ptr=100;
By this you are trying to store a int as an address to a pointer, which Is nonsense.
In other words you are trying to make the pointer ptr to point the address 100, which is not an address.
But by
*ptr=100;
You are trying to store value 100 to the address pointed by ptr, which is valid.
Also
ptr++;
Means that now ptr is pointing to ptr+4 or (ptr+2 for 16 bit compiler like tc) address.
Also for your particular code, you are just changing and incrementing the address pointed by ptr, but you are not storing any value at the address pointed by ptr.
So your code will print garbage value or it may also crash as 100 is not a valid address.
Also you should have done
ptr=(int*)100;
It would remove
warning: assignment makes pointer from integer without a cast [enabled by default]
But still it is undefined behaviour.

Why pointer is giving the same address for all array blocks?

Here is a program, I write it to output all the characters of a string one by one. But I also print the address of individual blocks of the array. The problem is addresses for all blocks are same. Why?
Does someone know?
#include<stdio.h>
int main()
{
char enter[]="Kinsman";
char *ptr;
ptr=enter;
int i=0;
while(*ptr!='\0')
{
printf("%c%p\n",*ptr,&ptr);
ptr++;
for(i=0;i<=100000000;i++);
}
return 0;
}
Because you print the address of the actual pointer.
When you use &ptr you get the address of the actual pointer and not the address if points to. Remove the ampersand (address-of operator &) so you have only ptr.
You are printing the address of the pointer, not the value of the pointer
Try
printf("%c%p\n",*ptr, static_cast<void*>(ptr));
(https://stackoverflow.com/a/18929285/259)
ptr is a pointer and it is also a variable in stack that has an address. This is fixed, while what it points to is varying by ptr++, thus you've to print the pointed-to value and not the address of the pointer itself.
printf("%c%p\n",*ptr, (void*)ptr);
// ^ remove & , and add void*

Resources