Redefining a corrupted reference - c++

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

Related

Understanding Delete in c++ [duplicate]

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;
}

question about modifying a pointer using another pointer in a function

I have a question about the following code. I am not sure why the address stored in yAdd doesn't get updated to the same address stored in the variable x inside the addfun() function in the code below? what is wrong with my thinking?
#include <iostream>
using namespace std;
void fun(int *x) {
*x = 55;
}
void addfun(int **x) {
*x = new int[3];
cout << x << endl; // x stores the address of int[0]
// say it is 0x7ffc32e646a0
cout << &x << endl;
}
int main()
{
int y = 99;
int *yAdd = &y;
cout << y << endl;
fun(yAdd);
cout << y << endl;
cout << yAdd << endl; // original address stored in yAdd
cout << "address of y is " << &y << endl;
addfun(&yAdd); // so I update the address stored in yAdd to be the same address
// as stored inside the x in the addfun function
cout << yAdd << endl; // but how come when printing this, yAdd doesn't
// show 0x7ffc32e646a0, but something else?
return 0;
}
addfun(&yAdd);
This is passing the address of yAdd to this function, as a parameter.
yAdd is a pointer. The pointer is an address of some other object in your program. It doesn't matter what that object is, yAdd is its pointer, and whatever yAdd itself, its address gets passed.
cout << yAdd << endl;
This shows the value of yAdd. Whatever this pointer is, its value is shown. And the address of this object, of yAdd, is something completely different.
void addfun(int **x)
x is a parameter to this function. x is a variable, that has nothing to do, whatsoever, with any other variable in your program. As such, it will have its own memory address, different than the memory address of everything else in your program (at least while it exists).
cout << &x << endl;
And this shows x's address. It is not showing the value of yAdd. It is not showing yAdds address, either. It is showing the address of x, a parameter to this function.
All of these are separate, distinct, objects and values in your program.
I changed the code to print out some more and label it better:
#include <iostream>
using namespace std;
void fun(int *x) {
*x = 55;
}
void addfun(int **x) {
cout << endl << "addfun()" << endl;
cout << "x = " << x << endl;
cout << "*x = " << *x << endl;
cout << "new int[3]" << endl;
*x = new int[3];
cout << "x = " << x << endl;
cout << "*x = " << *x << endl;
cout << "addfun() done" << endl << endl;
}
int main()
{
int y = 99;
int *yAdd = &y;
cout << y << endl;
fun(yAdd);
cout << y << endl;
cout << "&yAdd = " << &yAdd << endl;
cout << "yAdd = " << yAdd << endl;
cout << "*yAdd = " << *yAdd << endl;
cout << "address of y is " << &y << endl;
addfun(&yAdd); // so I update the address stored in yAdd to be the same address
// as stored inside the x in the addfun function
cout << "&yAdd = " << &yAdd << endl;
cout << "yAdd = " << yAdd << endl;
cout << "*yAdd = " << *yAdd << endl;
return 0;
}
This produces for example the following output:
99
55
&yAdd = 0x7ffc9e47fe58
yAdd = 0x7ffc9e47fe54
*yAdd = 55
address of y is 0x7ffc9e47fe54
addfun()
x = 0x7ffc9e47fe58
*x = 0x7ffc9e47fe54
new int[3]
x = 0x7ffc9e47fe58
*x = 0x564ab462d2c0
addfun() done
&yAdd = 0x7ffc9e47fe58
yAdd = 0x564ab462d2c0
*yAdd = 0
As you can see when you enter addfun the value of x is the address of yAdd which points to y. Then you allocate the int[3] and assign the result to *x. That is you store the address of int[3] into where x points to, namely yAdd. The value of x is not changed.
After the call to addfun you can see that the address of yAdd is still the same as and the same as x was but where yAdd points to has now been changed to int[3].
I think the bit where you got confused is *x = .... That changes the things x points at and not x itself.
Within the function addfun
void addfun(int **x) {
*x = new int[3];
cout << x << endl; // x stores the address of int[0]
// say it is 0x7ffc32e646a0
cout << &x << endl;
}
the statement
cout << x << endl; // x stores the address of int[0]
// say it is 0x7ffc32e646a0
prints the address of the original pointer yAdd passed to the function
addfun(&yAdd);
In main this statement
cout << yAdd << endl;
outputs the value assigned to the pointer within the function addfun in this statement
*x = new int[3];
that is the address of the dynamically allocated memory.
The assigned value to the pointer yAdd and the address of the pointer itself are two different values.

Explain C++ pointer initialization

int value = 3;
int *pValue1 = &value;
int *pValue2(pValue1);
cout << (*pValue1) << " " << (*pValue2);
In the above code if you have noticed I have written
int *pValue2(pValue1);
instead of
int *pValue2 = new int;
pValue2 = pValue1;
Still it is working and giving proper result.
Can any one explain to me which of the default function or constructor is getting called in this case?
int *pValue2(pValue1);
is equivalent to
int* pValue2 = pValue1;
Just assign to pValue2 pValue1 (assign to pValue2 address of variable value).
The difference should be apparent if you print the pointers themselves (the addresses) in addition to the values which they reference:
#include <iostream>
using namespace std;
int main() {
int value = 3;
int *pValue1 = &value;
int *pValue2(pValue1);
int *pValue3 = new int;
cout << pValue1 << " " << pValue2 << " " << pValue3 << endl;
cout << *pValue1 << " " << *pValue2 << " " << *pValue3 << endl;
pValue3 = pValue1;
cout << pValue1 << " " << pValue2 << " " << pValue3 << endl;
cout << *pValue1 << " " << *pValue2 << " " << *pValue3 << endl;
return 0;
}
You will also see that after new int, the memory pointed to by the pointer contains uninitialized data.

Displaying the Address of Chars

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.

Scope of object created using new

I am learning C++ as a hobby and am wrestling with using "new" to dynamically create a class object. I have read that dynamically created classes do not lose scope, but that does not seem to work for my simple example.
When executed, the value of 'testValue1' is set to 555 in the constructor and printed. When the control is returned to main, 'testvalue' is unfortunately set to 0 (or not defined--not sure). I can set the value inside of main and the value is properly maintained inside of main as well as in a for loop.
The problem: I don't understand why the initialized value of 555 is not maintained when control is returned to main. I know I am doing something wrong or not understanding scope for dynamically assigned class object properly...any assistance is appreciated. Here is the sample code:
//main.cpp
#include <iostream>
using namespace std;
class generalVars
{
private:
public:
//data attributes
int testValue1;
//constructor
generalVars()
{
cout << "I am in general vars constructor" << endl;
int testValue1= 555;
cout << "testValue1 has been set " << testValue1 << endl;
}
~generalVars(void)
{
cout << "I am in general vars destructor" << endl;
};
};
int main(int argc, char *argv[])
{
cout << "I am in Main" << endl;
generalVars* myGeneralVars = new generalVars; //create on heap
cout << "Main1 testvalue1 = " << myGeneralVars->testValue1 << endl;
myGeneralVars->testValue1 = 777;
cout << "Main2 testvalue1 = " << myGeneralVars->testValue1 << endl;
for (int i=0; i<= 3; i++)
{
cout << "Inside while loop..." << endl;
cout << "Main3 " << i << " testvalue1 = " << myGeneralVars->testValue1 << endl;
}
delete myGeneralVars; //delete from heap
return 0;
}
This statement:
int testValue1= 555;
declares a local variable, distinct from the data member of the same name.
So it doesn't change the value of the member.
Instead, do e.g.
testValue1= 555;
Or use the constructor's memory initializer list, like this:
generalVars()
: testValue1( 555 )
{
cout << "I am in general vars constructor" << endl;
cout << "testValue1 has been set " << testValue1 << endl;
}
You defined another variable in generalVars constructor and init value to 555, to init member testValue1, you don't need to define it again in constructor.
update
generalVars()
{
cout << "I am in general vars constructor" << endl;
int testValue1= 555; // this defines another testValue1 variable. it's different from member testValue1
cout << "testValue1 has been set " << testValue1 << endl;
}
to
generalVars()
{
cout << "I am in general vars constructor" << endl;
testValue1= 555; // Note, removed int
cout << "testValue1 has been set " << testValue1 << endl;
}
Two things are going on:
1) you re-declare testValue1 here by putting int in front:
generalVars()
{
cout << "I am in general vars constructor" << endl;
int testValue1= 555; //right here!
cout << "testValue1 has been set " << testValue1 << endl;
}
This hides the class's own instance of testValue1 with a new unique variable by the same name. You can reference both like so:
generalVars()
{
cout << "I am in general vars constructor" << endl;
int testValue1= 555; //note, still has int
cout << "testValue1 has been set " << testValue1 << endl;
cout << "this->testValue1 has not been set and is " << this->testValue1 << endl;
this->testValue1 = 555; //note, this->
cout << "this->testValue1 has been set " << this->testValue1<< endl;
}
Or you could avoid the name clash and refer to it normally:
generalVars()
{
cout << "I am in general vars constructor" << endl;
testValue1= 555; //note, no int. This is identical to this->testValue1
cout << "testValue1 has been set " << testValue1 << endl;
}
Next is not really an issue, but should be noted:
You do not need to heap allocate things with new in C++ most of the time. You should prefer stack allocated objects
generalVars myObject;
instead of:
generalVars *myObject = new generalVars();
...
delete myObject;
Or, in cases where you do want to create a heap allocated object:
auto myObject = std::make_unique<generalVars>();
Or, if you need multiple handles:
auto myObject = std::make_shared<generalVars>();
The unique_ptr and shared_ptr examples do not require explicit deletion. The heap allocation will be deleted when the pointer object goes out of scope. This especially helps with exception safety.