So we have an assignment in my C++ class to create a pointer to a char and the instructions are:
For each declaration make sure to:
Initialize the pointer to an appropriate address value
Show the contents of the pointer (match this value with the address of what is pointing to)
Show the contents of what the pointer points to (match this value with the original contents)
Whenever I try to display the address of char a with &a , it just outputs the value stored in char a rather than the address. When I try this with integers it works like I want it to.
Can anybody give me an idea as to what I'm doing wrong?
#include <iostream>
using namespace std;
int main()
{
// Question 1, Part I
// (a)
char a = 'A';
char * pa = &a;
//(b)
cout << "Address of a = " << &a << endl;
cout << "Contents of pa = " << pa << endl;
//(c)
cout << "Contents of a = "<< a << endl;
cout << "What pa points to = "<< *pa << endl;
return 0;
}
Edit & Run
When you give a pointer to char to cout, it will consider it as a null terminated c string.
Recast it to a void pointer:
cout << "Address of a = " << static_cast<void*>(&a) << endl;
The standard guarantees that the adress is unchanged in section 4.10/2:
A prvalue of type “pointer to cv T,” where T is an object type, can be
converted to a prvalue of type “pointer to cv void”. The result of
converting a non-null pointer value of a pointer to object type to a
“pointer to cv void” represents the address of the same byte in memory
as the original pointer value.
Here an explanation about pointer to char in output streams. And here an explanation why void* causes the value of the pointer to be displayed.
Change these statements
cout << "Address of a = " << &a << endl;
cout << "Contents of pa = " << pa << endl;
to
cout << "Address of a = " << ( void * )&a << endl;
cout << "Contents of pa = " << ( void * )pa << endl;
or
cout << "Address of a = " << reinterpret_cast<void *>( &a ) << endl;
cout << "Contents of pa = " << reinterpret_cast<void *>( pa ) << endl;
or
cout << "Address of a = " << static_cast<void *>( &a ) << endl;
cout << "Contents of pa = " << static_cast<void *>( pa ) << endl;
All three variants will work.
Related
This question already has answers here:
Using pointer after free()
(6 answers)
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 9 months ago.
I created a pointer code in which I played with pointers a little bit but when I tried to delete my pointer variable it still showed me the value which was stored in a pointer variable, after deletion I can still be able to use that pointer variable but I deleted that pointer variable so how can I reuse that after deleting? I don't get that.
Code:
#include<iostream>
int main()
{
using namespace std;
int *m = new int;
int *ab = new int;
cout << "Enter value of m: ";
cin >> *m;
cout << "Address of pointer m: " << m <<endl;
cout << "Content of pointer m: " << *m << endl;
ab = m;
cout << "Address of pointer ab: " << ab <<endl;
cout << "Content of pointer ab: " << *ab << endl;
*m = 34;
cout << "Address of pointer ab: " << ab <<endl;
cout << "Content of pointer ab: " << *ab << endl;
*ab = 7;
cout << "Address of pointer m: " << m <<endl;
cout << "Content of pointer m: " << *m << endl;
delete ab;
delete m;
cout << *m + 1 << endl; //this is giving me result of *m + 1 which is not ok cuz I deleted pointer variable on above line.
return 0;
}
class A
{
};
int main()
{
A *a= new A(); // variable "a" must be pointer, I can't edit this line
A& b = *a; //b must be a reference
delete a; //deletion
a= new A(); //re-definition
//b is now corrupted.
}
In a piece of code that I have to work with, a pointer to an object of class A is created and a reference to this pointer too.
For some reasons, I have to delete the pointer and re-defined it. How can I get b to work again ?
You can do this, subject to some constraints:
A* a = new A(); // variable "a" must be pointer, I can't edit this line
A& b = *a; // b must be a reference
a->~A(); // destroy first object
new (a) A(); // create second, new object in its place
delete a; // destroy second object and release memory
The constraints are if A contains non-static const data members, you cannot use b after the reconstruction.
(Starting with C++17, you can reuse a reconstructed object even if it has const members by using some extra acrobatics: A& b2 = *std::launder(a); But you still cannot reuse b as is.)
in your code you are not using a reference to a pointer, to do so:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int* ptrA = new int(77);
int*& rPtrA = ptrA; // this a reference to a pointer
cout << "ptrA: " << ptrA << endl;
cout << "*ptrA: " << *ptrA << endl;
cout << "rPtrA: " << rPtrA << endl;
cout << "*rPtrA: " << *rPtrA << endl;
delete ptrA;
ptrA = NULL;
cout << "ptrA: " << ptrA << endl;
// cout << "*ptrA: " << *ptrA << endl; // cause runtme error
cout << "rPtrA: " << rPtrA << endl;
// cout << "*rPtrA: " << *rPtrA << endl;// cause runtme error
ptrA = new int(100);
cout << "ptrA: " << ptrA << endl;
cout << "*ptrA: " << *ptrA << endl;
cout << "rPtrA: " << rPtrA << endl;
cout << "*rPtrA: " << *rPtrA << endl;
delete rPtrA; // delete pointer through its reference
rPtrA = NULL;
cout << "ptrA: " << ptrA << endl;
// cout << "*ptrA: " << *ptrA << endl; // runtime error
cout << "rPtrA: " << rPtrA << endl;
// cout << "*rPtrA: " << *rPtrA << endl; // runtime error
return 0;
}
&* is used for reference to pointer not just &.
a reference is a just another pseudonym to a variable so whatever the variable changes the reference changes also.
a reference to a pointer REFERS to the POINTER'S ADDRESS not the address the pointer stores (value of pointer).
in your code you used a reference to the value(what pointer stores not the pointer itself) the pointer points to
char testChar = 'a';
char myCharString[] = "asd";
char *pointerToFirstChar = &(myCharString[0]);
char *pointerToSecondChar = &(myCharString[1]);
cout << "A char takes " << sizeof(testChar) << " byte(s)";
cout << "Value was " << pointerToFirstChar << ", address: " << &pointerToFirstChar << endl;
cout << "Value 2 was " << pointerToSecondChar << ", address:" << &pointerToSecondChar << endl;
this outputs:
"A char takes 1 byte"
"... address: 00F3F718"
"... address: 00F3F70C",
I'm thinking the difference between addresses should be 1 byte, since that would be the size of the data separating them. Why is it not so?
&pointerToFirstChar and &pointerToSecondChar, you're not taking the address of the elements of the char array, but the address of the local variable pointerToFirstChar and pointerToSecondChar. Note they've been pointers themselves.
You might want:
cout << "Value was " << pointerToFirstChar << ", address: " << static_cast<void*>(pointerToFirstChar) << endl;
cout << "Value 2 was " << pointerToSecondChar << ", address:" << static_cast<void*>(pointerToSecondChar) << endl;
Note you need to cast them to void* to print out the address instead of the string.
You're looking at the addresses of the pointers pointerToFirstChar and pointerToSecondChar. They are pointers to char; compare their values and those will differ by 1. You seem to have edited that out in your text.
you are printing address of pointer variable and not the address currently pointer is holding.
for example:
&myCharString[0] = 0xFE20
&myCharString[1] = 0xFE21
&myCharString[2] = 0xFE23
char *pointerToFirstChar = &(myCharString[0]);
Address of pointerToFirstChar = 0xF8C2 and it holds the address &myCharString[0] = 0xFE20
so you are printing, 0xF8C2 rather than printing 0xFE20
Update your code as follows to get the correct result.
cout << "Value was " << pointerToFirstChar << ", address: " << (void *)&pointerToFirstChar[0] << endl;
cout << "Value 2 was " << pointerToSecondChar << ", address:" << (void *)&pointerToSecondChar[0] << endl;
For more information please follow the below link
print address of array of char
The code works as expected until the lines 22-24, where we are printing 8 followed by address. Incrementing the pointer address increments the address by one byte only, whereas it should move address by 4 bytes. The problem does not occur in arrays or if lines 22-24 are run separately.
#include<iostream>
using namespace std;
void main()
{
int *p;
//int a[10] = { 0 };
//p = a;
int a = 100;
p=&a;
cout << "1. "<<p <<" "<<*p<< endl;
p++;
cout << "2. " << p << " " << *p << endl;
++p;
cout << "3. " << p << " " << *p << endl;
++*p;
cout << "4. " << p << " " << *p << endl;
++(*p);
cout << "5. " << p << " " << *p << endl;
++*(p);
cout << "6. " << p << " " << *p << endl;
*p++;
cout << "7. " << p << " " << *p << endl;
(*p)++; //This is the problem, increments the address by 1, even though its in int type
cout << "8. " << p << " " << *p << endl;
*(p)++;
cout << "9. " << p << " " << *p << endl;
*++p;
cout << "10. " << p << " " << *p << endl;
*(++p);
cout << "11. " << p << " " << *p << endl;
cin.get();
}
Initially you set p to point to an integer variable on the stack. When you subsequently increment the pointer you are pointing to an area of memory on the stack which is likely to change when a function is called ( cout for example). when the function returns it will probably have changed the memory location that your incremented pointer p is pointing to and this probably explains your issue.
You should declare an array large enough to accommodate the range of pointer addresses that you are going to step through. I notice that you commented out the array code which would have worked as you expected.
Your code is:
p = &a;
p++;
Now p is pointing past the end of a. This is still OK, however on the next line:
cout << "2. " << p << " " << *p << endl;
when you write *p this tries to read the memory past the end of a, which causes undefined behaviour.
When undefined behaviour has happened, the definition of the C++ language no longer covers what the program does. Anything can happen.
To put it another way: when generating the executable, the compiler can make assumptions based on the premise that your program only does things which are well-defined.
Your output could perhaps be explained by the compiler making such an assumption which would be justified if your program were confirming, but is actually false because your program is invalid.
One explanation that comes to mind is that you advanced p until it happens to be pointing to the memory location in which p itself is stored. The compiler implements (*p)++ by outputting an instruction for incrementing an int stored at the location where p is pointing. On your system, the result of applying this instruction to the location where actually p is stored is to increase the address value of p by one.
I'm struggling a little bit with my understanding concerning the actual mechanism in dereferencing pointers (what the compiler actually does).
I red a lot through google and on here on stackoverflow, but I coulnd't quite get it yet :-(
I wrote a simple program with multiple pointers:
#include <iostream>
int main()
{
int a = 5;
int* ptr = &a;
int** pptr = &ptr;
int*** ppptr = &pptr;
int**** p4tr = &ppptr;
std::cout << "a = 5 \nint*ptr = &a \nint** pptr = *ptr\nint*** ppptr = &pptr\nint**** p4tr= &ppptr\n" << std::endl;
std::cout << "a: " << a << std::endl;
std::cout << "&a: " << &a << std::endl << std::endl;
std::cout << "ptr: " << ptr << std::endl;
std::cout << "*ptr: " << *ptr << std::endl;
std::cout << "&ptr: " << &ptr << std::endl << std::endl;
std::cout << "pptr: " << pptr << std::endl;
std::cout << "*ptr: " << *pptr << std::endl;
std::cout << "**pptr: "<< **pptr << std::endl;
std::cout << "&pptr: " << &pptr << std::endl << std::endl;
std::cout << "ppptr: " << ppptr << std::endl;
std::cout << "*ppptr: " << *ppptr << std::endl;
std::cout << "**pptr: " << **ppptr << std::endl;
std::cout << "***pptr: " << ***ppptr << std::endl;
std::cout<< "&pptr: " << &ppptr << std::endl << std::endl;
std::cout << "p4tr: " << p4tr<< std::endl;
std::cout << "*p4tr: " << *p4tr<< std::endl;
std::cout << "**p4tr: " << **p4tr<< std::endl;
std::cout << "***p4tr: " << ***p4tr<< std::endl;
std::cout << "****p4tr: " << ****p4tr<< std::endl;
std::cout << "&p4tr: " << &p4tr<< std::endl << std::endl;
return 0;
}
Which gives me this on my machine:
a = 5
int*ptr = &a
int** pptr = *ptr
int*** ppptr = &pptr
int**** p4tr= &ppptr
a: 5
&a: 0x7fffe4db870c
ptr: 0x7fffe4db870c
*ptr: 5
&ptr: 0x7fffe4db8700
pptr: 0x7fffe4db8700
*ptr: 0x7fffe4db870c
**pptr: 5
&pptr: 0x7fffe4db86f8
ppptr: 0x7fffe4db86f8
*ppptr: 0x7fffe4db8700
**pptr: 0x7fffe4db870c
***pptr: 5
&pptr: 0x7fffe4db86f0
p4tr: 0x7fffe4db86f0
*p4tr: 0x7fffe4db86f8
**p4tr: 0x7fffe4db8700
***p4tr: 0x7fffe4db870c
****p4tr: 5
&p4tr: 0x7fffe4db86e8
What I figured out, how dereference works is:
int* ptr = &a; tells the compiler that the "variable" ptr is of type "int*" (pointer to an interger; i.e. memory address)
Hence, when I write *ptr, the compiler takes the value of ptr, takes it as an address and interpretes what is stored at the very address as type int.
So far, so good.
But what does int** pptr = &ptr actually mean to the compiler ?
Does it mean pptr is of type " int** " ?
or does it still mean pptr is of type " int* " (i mean, &ptr is as good a memory address as &a)
What does the second asterix actually mean to the compiler and why can't I write: "int* pptr = &ptr"
(at least g++ won't let me do that)
thank you so much for your efforts,
it hurts my brain, if things seem unlogical to me :-))
But what does int** pptr = &ptr actually mean to the compiler? Does it mean pptr is of type int**?
Yes, pptr is of type int**. And int** is pointer to pointer to int. So *pptr has type int*, and **pptr has type int.
Why can't I write: int* pptr = &ptr?
Well, ptr has type int*. And so &ptr has type int** which is not assignment compatible with a variable of type int*. A pointer to int is a different type of thing to a pointer to pointer to int.