C++ How to properly copy the value of a pointer - c++

So I'm having a bit of an issue, and need help with this beginner question.
I've changed my example so that it makes sense. I should not have posted one while sleep deprived.
I'm trying to copy a pointer (lets call it p1) in order to create a second pointer (lets call it p2).
When p1 changes the object it is pointing at, I don't want p2 to change along with it, which is what appears to be happening in my program.
Essentially, here is the issue I'm having....
#include <string>
#include <iostream>
int main(){
std::cout << "Pointer Test\n\n";
int num1, num2;
int * p1, * p2;
num1 = 5;
num2 = 10;
p1 = &num1;
p2 = p1;
std::cout << "P1 is pointing at value " << *p1 << " (should be 5)\n";
std::cout << "P2 is pointing at value " << *p2 << " (should be 5)\n\n";
*p1 = num2; //Even though the value of P1 is changing, I don't want the value of P2 to change. I want it to stay on num1
std::cout << "P1 is pointing at value " << *p1 << " (should be 10)\n";
std::cout << "P2 is pointing at value " << *p2 << " (I want this to be 5, not 10)\n";
return 0;
}
/*
Assignments I've tried to make this work...
p2 = p1; //didn't work - *p2 changes when *p1 does, which I am trying to avoid
*p2 = *p1; //didn't work - caused segfault
*p2 = p1; //didn't work - can't convert int to *int, so won't compile
p2 = &(*p1); //didn't work - gave same result as p2 = p1
*/
Any enlightenment on this matter would be greatly appreciated.

I think you have a misunderstanding of what is going on. The statement *p1 = num2; is not changing the value of p1, it is changing the value of whatever p1 points to. Since both p1 and p2 point to the same variable when you change its value through one pointer you will see the same value when you dereference either pointer. What you want to do is have p1 point to num2, not take the value of num2 and store it in whatever p1 points to.
Change
*p1 = num2;
to
p1 = &num2;

Consider the following code:
int a = 5, b = 10, *foo, *bar;
foo = &a; // foo now points at the address of A
bar = foo; // bar now points at the address at which foo is pointing
foo = &b; // foo now points at the address of B
cout << *foo; // prints 10
cout << *bar; // prints 5
Thats the behaviour you want to achieve if Im not mistaken.
Your code is nonsensical however. IF I'm not wrong, your mistake is that you create a second pointer which points at the address of the first pointer instead of pointing at the address from the first pointer.

Your first code makes no sense. If testObj isn´t a typedef to a pointer,
the * in the first p1 assignment is wrong (it should be &), and the second p1 assignment is wrong too, because you can´t assign a temporary object to a pointer, (only addresses to variables or from new).
And always remember to assign an address to a pointer p before using *p
If you want to copy pointers, the copy will point to the same thing as the original one and p2 = p1; is correct. If you want to copy objects, the pointer thing has nothing to do with it, and how the object is copied should be defined in a copy constructor and operator=.
Depending on the class, memcpy can work or not, don´t rely on it for such cases.

Nonsensical code aside
When p1 changes the object it is pointing at, I don't want p2 to change along with it
If p1 and p2 point to the same object, changing the object p1 points to will change the (same) object p2 points to, period. You'll have to use a different mechanism than raw pointers to avoid that behaviour. Like making copies of the object pointed to instead of copying the pointer.
Also
Do I have to use memcpy? Or is there another way?
Since this is C++, I'd avoid memcpy.
Defining a copy constructor or assignment operator is a better way of copying objects.

There is no type like obj *. The "*" binds tighter to "p1". So you need to change the decl from
obj * p1, p2;
To
obj *p1, *p2;

Related

How does this work? Pointer to pointer assignment

#include <iostream>
using namespace std;
int main() {
int *p1;
p1 = new int;
int *p2;
p2 = new int;
p2 = p1; // what happens here?
*p1=5;
cout << "pointer 2 is " << *p2 << endl << *p1 << endl; // both give out 5
delete p1; // what happens to p2 ?
cout << "pointer 2 is " << *p2 << endl;
delete p2;
return 0;
}
What happens when I delete the pointer object p1? What is pointer p2 referencing now ? Can some one explain ? Thanks for the help
What is pointer p2 referencing now ?
Nothing. It's dangling. It was pointing to the same thing p1 was pointing to, but you've deleted that.
Consequently, your *p2 is broken, as is your delete p2; these both have undefined behaviour.
You've also leaked the second new int, because p2 used to point to it but stopped doing so when you wrote p2 = p1 (you changed it to point to the first new int instead, like p1 does), and there's no other way to refer to it.
p2 = p1; // what happens here?
You are simply copying the value (pointed memory address) of p1 into p2. This is no different than doing this:
int i1, i2;
i1 = 12345;
i2 = i1;
However, because the value in question in a memory address allocated with new, you now have a memory leak, as you have lost your only pointer to the 2nd allocated int that p2 was previously pointing at. Now p1 and p2 are both pointing at the 1st int in memory.
cout << "pointer 2 is " << *p2 << endl << *p1 << endl; // both give out 5
Yes, because p1 and p2 are pointing at the same memory address.
delete p1; // what happens to p2 ?
Nothing happens to p2 here, it is still pointing at the same memory address it was before. p1 and p2 are independent variables, so a change to one does not affect the other. But, the delete has deallocated the 1st int that was stored at the memory address being pointed at by p1 and p2, so now they are both dangling pointers to invalid memory. Since you don't use p1 after this, that is ok for p1, but for p2 the next statements:
cout << "pointer 2 is " << *p2 << endl;
delete p2;
Will cause Undefined Behavior, because you are accessing invalid memory via the dangling p2. The read may succeed in returning stale data that is still present at the memory address, or it may return garbage, or it may crash. The delete will almost certainly crash, since the memory has already been freed earlier, but that is not guaranteed either. Undefined Behaivor is just that - undefined - so literally anything could happen.

I am getting a issue in copying a pointer to another pointer in c++

I am getting segmentation fault in first code but the second code is running fine, don't know how?
How can I copy a pointer and save it to another pointer?
#include <iostream>
using namespace std;
int main() {
int *p;
int *p1;
*p1=7;
p=p1;
cout<<*p<<" "<<p;
return 0;
}
#include <iostream>
using namespace std;
int main() {
int *p1;
*p1=7;
int *p=p1;
cout<<*p<<" "<<p;
return 0;
}
//7 0x7ffeea73db70
Both cases invoke undefined behaviour, in both cases you make use of uninitialized pointer p1, the fact that the second case "works" for you is a matter of sheer luck, as you can see here.
For your code to be valid you need to make it point to a valid memory address either by allocating memory manually:
int *p1 = new int; //raw pointer, (better to use smart pointers* but let's not get ahead of ourselves).
Or by assigning it the address of a valid int variable:
int i = 5;
int *p1 = &i;
How can I copy a pointer and save it to another pointer?
A pointer is essentially a variable like any other, you can copy it like you do a normal primitive variable, in fact you do just that when you do p = p1, these are two different pointers that will now contain the same value, the address of the variable they point to.
This code exemplifies this
#include <iostream>
using std::cout;
using std::endl;
int main() {
int *p1 = new int;
*p1 = 7;
int *p = p1;
cout<< "Value stored in the address p points to: " << *p << endl
<< "Value stored in the address p1 points to: " << *p1 << endl
<< "Address where p points to: " << p
<< " " << endl << "Address where p1 points to: "<< p1
<< endl << "Address of p: " << &p << endl << "Address of p1: "<< &p1;
return 0;
}
The output:
Value stored in the address p points to: 7
Value stored in the address p1 points to: 7
Address where p points to: 0x804150
Address where p1 points to: 0x804150
Address of p: 0x7ffc9447e220
Address of p1: 0x7ffc9447e228
*What is a smart pointer and when should I use one?
When you dereference an int* pointer, you promise that there is an int object at that address. C++ believes you, often without questioning. But you never wrote int a; p1=&a; or any other code that made sure p1 points to an actual int.
In fact, p1 isn't even a null pointer. The only thing you can do with p1 is to assign it a legal value. That is to say, it must appear at the left-hand side of an assignment first. It can't be used on the right hand side in int* p = p1;

Two pointers to the same location?

I can't seem to find the answer on here, but I'm sorry if this is a duplicate. Here's my question: When I have two pointers to the same location, then I change the address of one (let's say pointer A), will I (by accident) be changing the address of the other pointer (pointer B)? Or will pointer B's location stay the same?
Changing the contents of a pointer (as opposed to the object being pointed to) will not affect other pointers to the same object.
Picture speaks a thousand words.
Pointers are pointing to another memory place, at the same time, they have their own memory space.
Two pointers, A and B point to the same place, yet, they are kept in separate memory locations. (Left half of the image)
If you change B, you will only change what B is pointing, A remains the same. (Right half of the image)
Pointer B's location will stay the same.
Because pointer A and pointer B are different pointer,they have different memory address.That means they are independent each other although both of them point to the same memory address.
But you should be careful when you try to change pointer A's content,this operation may cause pointer B be a wild pointer by accident!
A pointer holds the memory address of a piece of data in memory.
The value of the pointer variable is this address.
int targetA = 1;
int targetB = 2;
int *pointerA = &targetA;
int *pointerB = &targetA;
printf("%p, %p\n", pointerA, pointerB);
// => 0x7fff5c78e8f8, 0x7fff5c78e8f8
pointerB = &targetB;
printf("%p, %p\n", pointerA, pointerB);
// => 0x7fff5c78e8f8, 0x7fff5c78e8f4
By assigning a different address / location to the pointer you just change what it points to, other variables are not affeted.
You can see the output of the below code :
#include <iostream>
int main(int argc, char **argv){
int a = 3, d = 4;
int *b = &a, *c = &a;
std::cout << b << ", " << c << std::endl;
b = &d;
std::cout << b << ", " << c << std::endl;
}
The following is the output of the code :
0x7ffca3788e40, 0x7ffca3788e40
0x7ffca3788e44, 0x7ffca3788e40
Clearly, changing the address b points to, has nothing to do with the address pointed by pointer c.
But you can have a near-similar phenomena when you use references. A reference is an entity that is an alias for another object. Suppose you have
int &ref = a;
ref = 5;
Now, changing the variable ref will also bring a change in the value of variable a, equating it to 5.
Let's take a look at this code snippet.
#include <iostream>
#include <string>
using namespace std;
int main ()
{
int * myp1, * myp2;
int myvalue;
myp1 = &myvalue;
myp2 = &myvalue;
myvalue = 10;
cout << "first address is " << myp1 << '\n';
cout << "second address is " << myp2 << '\n';
Here, the outputs are the same (when I run it, I get first address is 0x759ba27bb1d8
second address is 0x759ba27bb1d8).
int myvalue2;
myp1 = &myvalue2;
myvalue2 = 20;
cout << "first address is " << myp1 << '\n';
cout << "second address is " << myp2 << '\n';
return 0;
}
Here, the addresses are different, but myp2 points to the same address as above.
And it makes sense; you have two separate things pointing to the same address. Why would changing what one thing points to change the other?
A (possibly very bad analogy) would be: consider that you and someone on the other end of the world are pointing at the sky (say, at the same point in the sky). Then, you point at the ground. Just because you pointed at the ground, doesn't mean the other guy will stop pointing at the sky.
Hope that helps.

Not able to understand the notations : * and ** with pointers

I have a problem with the pointers. I know what this does:
*name
I understand that this is a pointer.
I've been searching but I do neither understand what this one does nor I've found helpful information
**name
The context is int **name, not multiplication
Could someone help me?
NOTE: Without the proper context, the usage of *name and **name is ambiguous. it may portrait (a). dereference operator (b) multiplication operator
Considering you're talking about a scenario like
char * name;
char **name;
in the code,
*name
name is a pointer to a char.
**name
name is a pointer, to the pointer to a char.
Please don't get confused with "double-pointer", which is sometimes used to denote pointer to a pointer but actually supposed to mean a pointer to a double data type variable.
A visual below
As above, we can say
char value = `c`;
char *p2 = &value; // &value is 8000, so p2 == 8000, &p2 == 5000
char **p1 = &p2; // &p2 == 5000, p1 == 5000
So, p1 here, is a pointer-to-pointer. Hope this make things clear now.
It's actually very simple, consider this:
int a; // a is an int
int* b; // b is a pointer to an int
int** c; // c is a pointer to a pointer to an int
If you see every level as just another variable type (so, see *int as a type), it's easier to understand.
Another example:
typedef int* IntPointer;
IntPointer a; // a is an IntPointer
IntPointer* b; // b is a pointer to an IntPointer!
Hope that helps!
pointer stores address of variable, pointer to pointer stores address of another pointer.
int var
int *ptr;
int **ptr2;
ptr = &var;
ptr2 = &ptr;
cout << "var : " << var;
cout << "*ptr : " << *ptr;
cout << "**ptr2 : " << **ptr2;
You can look here
int a = 5;// a is int, a = 5.
int *p1 = &a; // p1 is pointer, p1 point to physical address of a;
int **p2 = &p1; // p2 is pointer of pointer, p2 point to physical adress of p1;
cout<< "a = "<<a << " *p1 = "<<*p1<<" *(*p2) = " << *(*p2)<<endl;
**name in this case. Would be a pointer to a pointer.

Asserting that both pointers point to NULL is not happening after delete()

Given this little piece of code :
#include <iostream>
#include <assert.h>
using namespace std;
struct Foo
{
// something
};
int main()
{
Foo *p1 = new Foo;
Foo * p2 = p1;
assert(NULL != p1);
delete p1;
p1 = NULL;
assert(NULL != p2);
delete p2;
cout << "everything is cool!" << endl;
return 0;
}
When I delete p1 , the second assert (assert(NULL != p2);) is not failing , why ?
The output : everything is cool!
Then why the assert of p2 is not failing ?
When I delete p1 , the second assert (assert(NULL != p2);) is not
failing , why ?
Deleting p1 or assigning to it has no effect on p2 itself. After you delete p1, p2 still points to that address, i.e. to a defunct object. It becomes a so-called dangling pointer. Of course, accessing it or deleting it (which you're doing) is undefined behavior.
Watch the stars, in particular.
int i;
int *p1 = &i;
assert(p1 != NULL);
int *p2 = p1;
assert(p2 != NULL);
*p1 = 10;
assert(i == 10);
assert(*p2 == 10);
p1 = NULL; // does not affect the object p1 was pointing at
assert(i == 10);
assert(*p2 == 10);
assert(p2 != NULL); // (which we already know, if the previous assert didn't crash)
You're right to suspect that everything is not cool. The program invokes the delete operator twice on the same object (a "double free" error), which will tend to corrupt the heap. If the program continued, you would see undefined behavior at some point. Having undefined behavior rather defeats the point of writing a computer program. If you want to see errors like this immediately and unambiguously, run it under valgrind's memcheck or equivalent.
One of the biggest and most confusing-to-beginners misnomer in C++ is the term "deleting a pointer". This has undoubtedly originated from the fact that a delete expression takes a pointer as its argument:
T * p = new T; // #1
delete p; // #2
However, what's really going on is that line #1 creates a new, dynamic, unnamed object. Think about this again: There is no variable whose value is the object create in line #1. The object is really out of reach, as indeed it does not live in any scope. All we have is a pointer to it.
To end the lifetime of a dynamic variable, we have to use a delete expression. But since we already know that we can only ever really have a pointer the object, not the object itself*, the expression con­veni­ent­ly accepts a pointer to the object we're deleting.
So really we should say that in line #2 "we are deleting the object *p by giving a pointer to it to the delete expression" (namely &*p == p).
The pointer itself is entirely unaffected by the delete call.
*) Yes, we could also have a reference variable, like T & r = *new T;, but that would be insane.
delete p; doesn't affect p. It destroys the object that p points to and frees its memory. p still has the value that it had before.