after ptr++ pointer does not increment
1 #include<iostream>
2
3 int main() {
4
5 char *ptr;
6 char ch = 'A';
7 ptr = &ch;
8
9 std::cout << "pointer :" << &ptr << "\n";
10 ptr++;
11 std::cout << "pointer after ++ :" << &ptr << "\n";
12 return 0;
13 }
ikar$ g++ pointer_arth.cpp
ikar$ ./a.out
pointer :0x7ffeed9f19a0
pointer after ++ :0x7ffeed9f19a0
ikar$
You're incrementing the pointer, but outputting the address of the variable that holds the pointer itself (&ptr). You should output just ptr (and format it accordingly - see edit below).
Example:
#include <iostream>
int main() {
char data;
char *ptr = &data;
std::cout << "pointer:" << (unsigned long long)ptr << std::endl;
ptr++;
std::cout << "pointer incremented: " << (unsigned long long)ptr << std::endl;
}
Output:
pointer:140732831185615
pointer incremented: 140732831185616
Yes, printing just ptr will output garbage, so I converted the pointer to an integer (since pointers are memory addresses anyway).
As suggested in the comments, you can cast the pointer to void * when printing, which gives nicer formatting:
pointer:0x7ffee5467acf
pointer incremented: 0x7ffee5467ad0
Note how 0x7ffee5467acf == 140732745022159 != 140732831185615 - you'll get different outputs on each run because the kernel will load the executable into different places in memory.
EDIT: yes, the first version of this answer, about simply outputting ptr with std::cout << ptr, was incorrect, because the << operator is overloaded in such a way that it treats pointers to char as C-strings. Thus, that version would access potentially invalid memory and output garbage.
But the concept remains the same. Pointers to int, for example, don't have this "problem" and are printed as hexadecimal numbers, even without casting them to void *: Try it online!. The output shows that pointers are still incremented correctly by sizeof(int), which equals 4 on that machine.
Pointer is incremented successfully in your code.
You print the address of location which hold the pointer variable.
Actually, it is garbage after character -'A' if print 'ptr', you can understand and pointing to such un-handled memory location is not good.
Related
How come when I increment a pointer and then dereference it I get a random number?
Here is my code:
#include <iostream>
using namespace std;
int main(){
int reference = 10;
int *health = &reference;
int *health1 = health;
cout << "Health Address: " << health <<
"\nHealth1 Address: " << health1 <<
"\nReference Address: " << &reference << endl;
health1++;
cout << "Health1 value after being incremented then dereferenced: " << *health1 << endl;
}
My output is:
Health Address: 0x7fff5e930a9c
Health1 Address: 0x7fff5e930a9c
Reference Address: 0x7fff5e930a9c.
Health1 value after being incremented then dereferenced: 197262882
I was expecting to get a 0 since the next value of the next memory address would be null, but that is not the case in this situation.
I was expecting to get a 0 since the next spot in memory would be null, but that is not the case in this situation.
Your expectation is wrong. After you have incremented your pointer, it is no longer pointing to the valid memory buffer. Dereferencing it invokes an undefined behavior.
After you increase the pointer, it points to the memory not allocated and initialized by your program, so it's not null as you expected.
Each time you run your program, you may get a random integer.
I think your misunderstanding comes from the fact that you expect the pointer to point at the address of the next element of an array:
int myarray[] = { 1, 2, 3, 4, 5 };
int* parray = myarray;
std::cout << *parray << std::endl;
parray++; // increment the pointer, now points at the address of number 2
std::cout << *parray << std::endl;
But since there is no array in your example the incremented pointer points at the next memory block. The size in bytes of the type it points to is added to the pointer. What value lies there is anyone's guess:
int myvalue = 10;
int* mypointer = &myvalue;
mypointer++;
Dereferencing such pointer is undefined behavior. When you exceed the memory allocated to your process you will not get a pointer null value or a dereferenced value of 0.
Suppose X is the value of a pointer T *p;.
If p is incremented then, p will point to address X + sizeof(T)
*p will then give you the value stored at address X + sizeof(T). Now depending upon the validity of address X + sizeof(T), you will get the result which can be Undefined Behavior in case X + sizeof(T) is invalid.
(*health1)++;
you need to dereference the pointer as this would increment the address itself and not the value it is pointing at.
I am new to cpp and learning pointers. while practicing the codes i came across this. When i do &(a pointer), it gives an another memory location.i want to know what this address is. I assume its the location where the ptr is saved. it has to be saved somewhere though it has the memory of value variable.
#include<iostream>
using namespace std;
int main()
{
int v =6;
int *ptr;
ptr = &v;
cout << "1: " << ptr << endl;
cout << "2: " << *ptr << endl;
cout << "3: " << &ptr << endl;
return 0;
}
OUTPUT:
1: 0x29cc6c
2: 6
3: 0x29cc68
Correct.
Output 1 is the value of the pointer, which is the address that it points to.
Output 2 is the "dereferenced" pointer which means it is the value contained at Output 1 (the location the pointer is pointing to).
Output 3 is the location where the pointer (which contains the value from output 1) is being stored.
You got it perfectly right:
v is a variable, so &v is the adress where v is stored in memory;
ptr is a variable as well, so &ptr is the adress where ptr is stored in memory.
In your example, because these variables are stored one after the other (on the local stack), their adresses are only 4 bytes apart.
Consider the following example
I want to print the address of "hello", not of ptr
#include<iostream>
using namespace std;
int main()
{
char *ptr = "HELLO";
cout<<"VALUE OF ptr"<<ptr;
cout<<"ADDRESS OF ptr"<<&ptr;
cout<<"WANT TO PRINT ADDRESS OF STRING HELLO";
return 0;
}
The << operator for most types prints the value of the right operand. The << operator for char* is different in that it prints the string that the char* value points to; it dereferences the pointer, and then traverses the characters of the string, printing each one, until it reaches the terminating '\0' null character.
To print the pointer value rather than what it points to, just convert it to void*, since << for void* prints the actual pointer value:
cout << "The address of the string is " << (void*)ptr << "\n";
or, if you prefer:
cout << "The address of the string is " << static_cast<void*>(ptr) << "\n";
(Incidentally, ptr should be a const char* rather than a char*.
Cast it to any other pointer. (void*)ptr or reinterpret_cast<int*>(ptr) or something.
How to get address of a pointer in c/c++?
Eg: I have below code.
int a =10;
int *p = &a;
So how do I get address of pointer p?
Now I want to print address of p, what should I do?
print("%s",???) what I pass to ???.
To get the address of p do:
int **pp = &p;
and you can go on:
int ***ppp = &pp;
int ****pppp = &ppp;
...
or, only in C++11, you can do:
auto pp = std::addressof(p);
To print the address in C, most compilers support %p, so you can simply do:
printf("addr: %p", pp);
otherwise you need to cast it (assuming a 32 bit platform)
printf("addr: 0x%u", (unsigned)pp);
In C++ you can do:
cout << "addr: " << pp;
int a = 10;
To get the address of a, you do: &a (address of a) which returns an int* (pointer to int)
int *p = &a;
Then you store the address of a in p which is of type int*.
Finally, if you do &p you get the address of p which is of type int**, i.e. pointer to pointer to int:
int** p_ptr = &p;
just seen your edit:
to print out the pointer's address, you either need to convert it:
printf("address of pointer is: 0x%0X\n", (unsigned)&p);
printf("address of pointer to pointer is: 0x%0X\n", (unsigned)&p_ptr);
or if your printf supports it, use the %p:
printf("address of pointer is: %p\n", p);
printf("address of pointer to pointer is: %p\n", p_ptr);
&a gives address of a - &p gives address of p.
int * * p_to_p = &p;
Having this C source:
int a = 10;
int * ptr = &a;
Use this
printf("The address of ptr is %p\n", (void *) &ptr);
to print the address of ptr.
Please note that the conversion specifier p is the only conversion specifier to print a pointer's value and it is defined to be used with void* typed pointers only.
From man printf:
p
The void * pointer argument is printed in hexadecimal (as if
by %#x or %#lx).
You can use the %p formatter. It's always best practice cast your pointer void* before printing.
The C standard says:
The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printing characters, in an implementation-defined manner.
Here's how you do it:
printf("%p", (void*)p);
You can use %p in C
In C:
printf("%p",p)
In C++:
cout<<"Address of pointer p is: "<<p
you can use this
in C
int a =10;
int *p = &a;
int **pp = &p;
printf("%u",&p);
in C++
cout<<p;
In C++ you can do:
// Declaration and assign variable a
int a = 7;
// Declaration pointer b
int* b;
// Assign address of variable a to pointer b
b = &a;
// Declaration pointer c
int** c;
// Assign address of pointer b to pointer c
c = &b;
std::cout << "a: " << a << "\n"; // Print value of variable a
std::cout << "&a: " << &a << "\n"; // Print address of variable a
std::cout << "" << "" << "\n";
std::cout << "b: " << b << "\n"; // Print address of variable a
std::cout << "*b: " << *b << "\n"; // Print value of variable a
std::cout << "&b: " << &b << "\n"; // Print address of pointer b
std::cout << "" << "" << "\n";
std::cout << "c: " << c << "\n"; // Print address of pointer b
std::cout << "**c: " << **c << "\n"; // Print value of variable a
std::cout << "*c: " << *c << "\n"; // Print address of variable a
std::cout << "&c: " << &c << "\n"; // Print address of pointer c
First, you should understand the pointer is not complex. A pointer is showing the address of the variable.
Example:
int a = 10;
int *p = &a; // This means giving a pointer of variable "a" to int pointer variable "p"
And, you should understand "Pointer is an address" and "address is numerical value". So, you can get the address of variable as Integer.
int a = 10;
unsigned long address = (unsigned long)&a;
// comparison
printf("%p\n", &a);
printf("%ld\n", address);
output is below
0x7fff1216619c
7fff1216619c
Note:
If you use a 64-bit computer, you can't get pointer by the way below.
int a = 10;
unsigned int address = (unsigned int)&a;
Because pointer is 8 bytes (64 bit) on a 64-bit machine, but int is 4 bytes. So, you can't give an 8-byte memory address to 4 bytes variable.
You have to use long long or long to get an address of the variable.
long long is always 8 bytes.
long is 4 bytes when code was compiled for a 32-bit machine.
long is 8 bytes when code was compiled for a 64-bit machine.
Therefore, you should use long to receive a pointer.
If you are trying to compile these codes from a Linux terminal, you might get an error saying
expects argument type int
Its because, when you try to get the memory address by printf, you cannot specify it as %d as its shown in the video.
Instead of that try to put %p.
Example:
// this might works fine since the out put is an integer as its expected.
printf("%d\n", *p);
// but to get the address:
printf("%p\n", p);
Building off the above answers, if you had the pointer as a private variable, then you can make a getter function like so:
private int* p;
public int** GetP() { return &p; }
Then when you use it you create a pointer to your class that contains it:
DummyClass* p_dummyClass = new DummyClass;
And then in your use case scenario:
p_dummyClass -> GetP();
(don't forget to deallocate)
static inline unsigned long get_address(void *input){
unsigned long ret;
__asm__(
".intel_syntax noprefix;"
"mov rax, %1;"
"mov %0, rax;"
".att_syntax;"
: "=r"(ret)
: "r"(input));
return ret;
}
So given the following code:
#include <iostream>
#include <vector>
int main(int argc, char* argv[]) {
int i = 42;
int* p = &i;
std::cout << "*p: " << *p << std::endl;
std::cout << "&p: " << &p << std::endl;
std::cout << "p: " << p << std::endl;
std::cout << "p + 1: " << (p + 1) << std::endl;
std::cout << "p + 1: " << ((p + 1) == (int*)(&p)) << std::endl;
std::cout << "*(p + 1): " << *(p + 1) << std::endl;
return 0;
}
It might produce the following output:
*p: 42
&p: 0x7fff38d8a888
p: 0x7fff38d8a884
p + 1: 0x7fff38d8a888
p + 1: 1
*(p + 1): 953723012
Is (p + 1) a pointer to the memory location p is stored in? Is it possible to get the value pointed by p by this way?
p is the pointer to an int object.
&p is the address of p.
The stack from your example looks like:
Address Type Name Value
0x7fff38d8a884 int i 42
0x7fff38d8a888 int* p 0x7fff38d8a884
The way that the stack has been setup, the address of p is right after the address of i. In this particular case, when you added 1 to p, it moved 4 bytes down and found the value there, which happens to be the address to i.
What is happening in the line
std::cout << "p + 1: " << ((p + 1) == (int*)(&p)) << std::endl;
is p+1 --> compiler gets address for the "second element" of array p
(int*)(&p) --> &p is an int**, but is being cast to an int*, int this particular instance, that happens to be the same as the value stored in p + 4 bytes
What is happening in the line
std::cout << "*(p + 1): " << *(p + 1) << std::endl;
is *(p+1) --> compiler accesses the "second element" of array p, because you are likely using an x86_64 system, which is little endian, the hex value stored there is 0x38D8A884, the lower half of the pointer stored in p (which converts to 953723012 in decimal),.
In your example (p + 1) does not point to any storage you have allocated, so dereferencing it produces undefined behavior and should be avoided.
EDIT: Also, your second output for (p + 1) itself is unreliable, since pointer arithmetic should be used only if the pointer is a pointer to an array. Consequently, the expression evaluates to false on my machine.
If you remember that pointers and arrays can be used interchangeably, you might figure out that e.g.
p[1]
is the same as
*(p + 1)
That means that the expression (p + 1) is a pointer to the int value after p. As p doesn't point to an array, it means that (p + n) for a positive n is a pointer to something you haven't allocated (it's out of bounds), and reading that value leads to undefined behavior. Assigning to it is also undefined behavior, and can even overwrite other variables data.
To get the address of where p is stored, you use the address-of operator: &p. That returns a pointer to the pointer (i.e. of type int **).
While the standard gives you no guarantee that ((p + 1) == (int*)(&p)) you seem to be lucky here.
Yet since you are on a 64-bitmachine when dereferencing (p+1) you get only the lower 32 bits of p.
0x38D8A884 == 953723012
The right hand side of the equation is the output that you received. The left hand side is the lower 32 bits of p as witnessed by the output of your program.
No.
Pointer arithmetic, although unchecked, is very limited by the Standard. In general, it should only be used within an array, and you may use it to point to either an array element or one past the end of the array. Furthermore, although pointing one past the end of an array is allowed, the so-obtained pointer is a sentinel value which should not be dereferenced.
So, what is it that you observe ? Simply put, &p, p + 1, etc... are temporary expressions whose result have to be materialized somewhere. With optimizations on, said results would probably be materialized in CPU registers, but without they are materialized on the stack within the function frame (in general).
Of course, this location is not prescribed by the Standard, so trying to obtain it produces undefined behavior; and even though it appears to work on your compiler with this set of compiling options means nothing for any other compiler or even this very same compiler with any other set of options.
That is the true meaning of undefined behavior: it does not mean the program crashes, it just means anything may happen and this encompasses the seems to work situations.
It is a random case that p + 1 is equal to &p. It takes place only in such code as yours where pointer p follows the object it points to. That is the address of p itself is sizeof( int ) greater than the address of the object it points to. If you for example will insert one more definition between i and p then the equation p + 1 == &p will not be valid. For example
int i = 42;
int j = 62;
int* p = &i;
p just so happened to get allocated on the stack at the address right after (well 4 bytes after) the address of the integer i. some_ptr+1 (which is really some_ptr+1*sizeof(int)) is not a consistent way to get the address of some_ptr, it is just a coincidence in this case.
so to answer your question some_ptr+1 != &some_ptr