Please don't come and say "jUst read the error", it doesn't specify it, that's why Im asking here.
int main()
{
int* p, * q;
int a = 10;
p = new int;
p = &a;
delete p;
}
p = new int
In this line, you dynamically allocate the memory that you need to delete.
p = &a
But in this line, you are not allocating new memory, you are pointing p at stack memory, and leaking the memory that you previously allocated.
I want to know if I create an array on the Heap in C++ and I assign data from the stack to the Array, what exactly happens? Is the data copied onto the heap?
code fragment:
int a = 1;
int b = 2;
int *c = new int(3);
int *arr = new int[3];
arr[0] = a;
arr[1] = b;
arr[2] = *c;
int a = 3;
a has the value 3.
the memory address of a is 0x345A or something like it.
a is on the stack.
int *p = &a;
pointer p is assigned the address of a. The memory address of p is 0x123B or something like it. That memory address holds the value 0x345A pointing to the location where the value 3 is stored. Pointer p is on the stack.
You'd get 3 if you print a and *p since they are getting their value from the same memory location.
You'd get 0x345A if you print &a and p since a's address is the value p holds.
You'd get 0x123B if you print &p since that is the memory location for pointer p.
Assuming *c points to an integer on the heap, you could store the value of c (which is the memory address of the integer on heap) in an array.
int *arr = new int[3];
...
arr[2] = c;
What you do NOT want to do is:
int foo = 10;
arr[2] = &foo;
Now, your array is pointing to a memory location that that is on the stack. Will work OK as long as you are in that function, but will be pointing at garbage once you exit the function and stack is reclaimed.
I'm having a hard time understanding how to tell between dangling pointers and memory leaks. I have a few questions on a recent assignment that are puzzling me, and after reading into it, I am still puzzled. I don't want someone to do my homework for me, I want to be able to understand why something is what it is, if that makes sense.
So, the homework:
Given the declarations:
int *ptrA, *ptrB;
Tell whether each code segment below results in a memory leak, a dangling pointer, or neither. Draw pictures to help.
I'm guessing that this is fine, as ptrA is already pointing to something in memory, so this one is neither a dangling pointer or a memory leak.
ptrA = new int;
ptrB = new int;
*ptrA = 345;
ptrB = ptrA;
I'm guessing that this is a dangling pointer because 345 was deallocated from memory, so ptrB points to nothing.
ptrA = new int;
*ptrA = 345;
ptrB = ptrA;
delete ptrA;
This is where I'm complete lost. Does the last line mean that the pointer is pointing to another pointer? Not sure what the implications of this would be.
ptrA = new int;
ptrB = new int;
*ptrA = 345;
*ptrB = *ptrA;
Like the previous question, I'm not sure what pointing to a pointer means, or if I even understand what this is achieving.
ptrA = new int;
ptrB = new int;
*ptrA = 345;
ptrB = new int;
*ptrB = *ptrA;
I know this is a dangling pointer, but I don't know why. Is it because the pointer is pointing to a local variable that went out of scope when the function finished?
ptrA = LocationOfAge();
where function LocationOfAge is defined as:
int *LocationOfAge() {
int age = 21;
return &age;
}
Thanks for anyone willing to help.
The rules of the game:
For every new Type draw a box. Put a question in the box (you don't know what is in there).
For every delete p cross out the box pointed to by p.
For every a = b (where there are no stars) draw a line from variable a to a box b.
For every *x = y write y inside the box pointed at by x.
For every *x = *y read the content of the box y and put a copy in x
The result:
When you have a box with no variables pointing at it you have a leak.
If you have a pointer that does not point at a box (or a crossed out box) you have a dangling pointer.
The first problem:
ptrA = new int;
ptrB = new int;
*ptrA = 345;
ptrB = ptrA;
Lets do this line by line:
ptrA = new int;
// Part 1 has a new so draw a box
*********
* ? *
*********
// Part 2 assignment to variable add a line
ptrA -------> *********
* ? *
*********
ptrB = new int;
// Part 3 has a new so draw another box
ptrA -------> *********
* ? *
*********
*********
* ? *
*********
// Part 4 assignment to variable add a line
ptrA -------> *********
* ? *
*********
ptrB -------> *********
* ? *
*********
*ptrA = 345;
ptrA -------> *********
* 345 *
*********
ptrB -------> *********
* ? *
*********
ptrB = ptrA;
ptrA -------> *********
| * 345 *
| *********
|
ptrB ---- *********
* ? *
*********
Seems like you have a leaked box. i.e. There is a box with no variable pointing at it.
I'm guessing that this is fine, as ptrA is already pointing to something in memory, so this one is neither a dangling pointer or a memory leak.
Yeah but now ptrB points to it too, and you have no way of freeing the thing that ptrB pointed to before.
So that's a leak.
I'm guessing that this is a dangling pointer because 345 was deallocated from memory, so ptrB points to nothing.
Correct.
Does the last line mean that the pointer is pointing to another pointer?
No, it gives <the thing that ptrB points to> the value of <the thing that ptrA points to>. No changes to the pointers involved, only int assignment.
Like the previous question, I'm not sure what pointing to a pointer means, or if I even understand what this is achieving.
The second new int is leaked, because the thing that used to point to it (ptrB) now points to a third new int and the former can no longer be freed.
I know this is a dangling pointer, but I don't know why. Is it because the pointer is pointing to a local variable that went out of scope when the function finished?
Yes.
To prevent making all homework, your first assumption is wrong.
1. ptrA = new int;
2. ptrB = new int;
3. *ptrA = 345;
4. ptrB = ptrA;
In line 1, ptrA creates a new integer (bytes are allocated), in line 2 ptrB allocates bytes. Than in 3, the memory allocated in 1 is filled, which is OK.
However, in line 4, ptrB is overwritten with the address of 3, this means the original addres of ptrB is not reachable anymore. And thus there is a memory leak, because the bytes allocated for the integer PtrB by line 2 can never be accessed anymore, since there is no pointer pointing to it.
It's much easier if you write a drawing, by using arrows for pointers and a box with either a ? for a declaration and a specific value when filled in. So it would look like:
1. ptrA -> [ ? ]
2. ptrA -> [ ? ], ptrB -> [ ? ]
3. ptrA -> [ 345 ], ptrB -> [ ? ]
4. ptrA -> [ 345 ] <- ptrB, [ ? ]
As you can see, the last box [ ? ] does not have any pointer pointing to it.
Let's take one question at a time.
ptrA = new int;
ptrB = new int;
*ptrA = 345;
ptrB = ptrA;
Here, it is a memory leak. Why? Because there is no delete first of all. Secondly, when you do ptrB = ptrA;, there is practically no way to call delete for the object that was pointed to by ptrB earlier.
ptrA = new int;
*ptrA = 345;
ptrB = ptrA;
delete ptrA;
This is an example of dangling pointer. Once delete is called on ptrA, the object pointed to by ptrA gets deallocated. So, ptrB points to a deallocated location whose behaviour is undefined. So, Dangling pointer!
ptrA = new int;
ptrB = new int;
*ptrA = 345;
*ptrB = *ptrA;
Here, there is memory leak simply because we are not calling delete. What we are doing is that we are creating two objects which are pointed by ptrA and ptrB respectively and both objects have value of 345. They still hold space in the heap. But how come both have the value of 345? Simple.
When you did *ptrA = 345;, it meant that the value of the object pointed to by ptrA should be set to 345.
When you did *ptrB = *ptrA;, it meant that the value of the object pointed by ptrB should be assigned with the value of the object pointed by ptrA.
This is the simple functioning of dereferencing operator.
ptrA = new int;
ptrB = new int;
*ptrA = 345;
ptrB = new int;
*ptrB = *ptrA;
This is similar to first one. In line 2, ptrB pointed to a dynamically allocated object. After execution of Line 4, ptrB points to entirely new object. So, there is no way to deallocate the object whose memory was allocated at line 2. So, Memory Leak!
int *LocationOfAge() {
int age = 21;
return &age;
}
Here, age is a local variable which will die once the function ends. So, any pointer to that local variable leads to undefined behaviour. So, Dangling Pointer!
What is the difference between these pointers?
I know that this one is going to be stored on the heap, even though a pointer is only 8 bytes anyways, so the memory is not important for me.
int* aa = new int;
aa = nullptr;
and this one is going to be stored on the stack.
int* bb = nullptr;
They both seem to work the same in my program. Is there any difference apart from memory allocation? I have a feeling that the second one is bad for some reason.
2) Another question which is somewhat related:
Does creating a pointer like that actually take more memory? If we take a look at the first snippet, it creates an int somewhere (4 bytes) and then creates a pointer to it (8 bytes), so is it 12 bytes in total? If yes are they both in the heap then? I can do this, so it means an int exists:
*aa = 20;
Pointers are integers that just indicate a memory position, and a type (so they can only point to variables of that type).
So in your examples, all pointers are stored in the stack (unless they are global variables, but that is another question). What they are pointing to is in the heap, as in the next example.
void foo()
{
int * ptr = new int(42);
// more things...
delete ptr;
}
You can have a pointer pointing into the stack, for example, this way:
void foo()
{
int x = 5;
int * ptr = &x;
// more things...
}
The '&' operator obtains the memory position of the variable x in the example above.
nullptr is the typed equivalent to old NULL. They are a way to initialize a pointer to a known and secure value, meaning that they are not pointing to anything else, and that you can compare whether they are NULL or not.
The program will accept pointers pointing to the stack or the heap: it does not matter.
void addFive(int * x)
{
*x += 5;
}
void foo()
{
int x = 5;
int * ptr1 = &x;
int * ptr2 = new int(42);
addFive( ptr1 );
addFive( ptr2 );
addFive( &x );
printf( "%d\n", *ptr1 );
printf( "%d\n", *ptr2 );
// more things...
delete ptr2;
}
The only difference is that the C runtime will keep structures telling how much memory has been spent in the heap, and therefore storing variables in the heap comes at a cost in performance. On the other hand, the stack is always limited to a fixed amount of memory (relatively small), while the heap is much larger, allowing you to store big arrays, for example.
You could take a look at C-Sim, which simulates memory in C (disclaimer: I wrote it).
Hope this helps.
I don't get that why reassigning a value to *p shows error. We've deleted it's resources, created at run time.
int a = 7, b = 8;
int *p = new int;
*p = a;
cout<<*p<<" "<<p<<endl;
delete p;
cout<<*p<<" "<<p;
*p = &b; // error
cout<<"\n"<<*p<<" "<<p;
The behaviour on dereferencing p after you've called delete p; is undefined. Don't do that. That's the easy bit. Now for the harder bit: the behaviour on reading the value of p (let alone dereferencing it) following a call to delete is undefined too! So don't do that either. (Informally you put the pointer back to an uninitialised state.)
*p = &b; is a typo. You need p = &b; to assign the pointer p to the address of b. If you fix that typo, you are free to read the value of p and dereference it once again.
The problem besides deleting the pointer and not giving it a new address is currently you are trying to assign the value of the p pointer to a memory address of an int.