I'm freshman in c++.
What's the difference between "delete a" and "delete b" ? Thanks a lot!
int* a = NULL ;
int* b = new int(10) ;
a = b;
delete a;//does the space of b free?
delete b;
ps:my bad!i dont mean delete a,b at same time,it's actually two ways of delete memery which i wanna ask.
Another question!
How to release the int allocated by the expression new int(10) in case 2?
//case 1: right
int *a= new int(10);
delete a;
//case 2:
int b = *new int(10); // how to release the int?
You called a single new, you need to a call a single delete. After a = b; you can delete either one. But you must delete only one. Deleting through either pointer will have the same effect. After the delete call, both variables will become invalid, pointing to freed memory.
Related
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'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!
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.
int main(){
int *a = new int[5];
int *b = new int[10];
int *c;
for (int i = 0; i < 5; ++i){
a[i] = i * i;
}
for (int i = 0; i < 10; ++i){
b[i] = 50;
}
c = a;
a = b;
delete[]b;
delete[]c;
return 0;
}
After the execution of code above, has the memory a originally pointed to been freed?
If not, how to free correctly?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pointer a has to be reserved for other uses, so it is prohibited to delete a directly.
the purpose of this code is to access the memory belonging to b originally via a and free the memory a used to possess correctly.
Yes, the memory is freed. However, be very careful when changing what a pointer points to because it can easily lead to memory leak.
Yes it has. Pointer are normal variables that happen to contain addresses. Since a is assigned to c. Your first allocation is freed.
It is freed.
Because after c = a;, c holds the memory address of a originally pointed to. And you have freed c by delete [] c;.
// Assume originally a -> 1, b -> 2
c = a; // Now a -> 1, b -> 2, c -> 1
a = b; // Now a -> 2, b -> 2, c -> 1
You can free a or b, at least one of them, they point to the same memory block. You must free c.
After the execution of code above, has the memory "a" originally
pointed to been freed?
Yes, the memory is freed. As c=a, delete [] c; clears the memory of a.
However, you don't need *c to clear memory, just directly delete a and b
delete[]a;
delete[]b;
UPDATE
As you have edited your answer and now it is more clear what you are trying to achieve,i.e. access memory pointed to by b via a but before that you want to free memory pointed to by a. So here's what you need to do:
1- First free the memory pointed to by a
delete []a;
2- Now point a to the memory location pointed to by b
a=b;
Now the memory location originally pointed to by a is cleared and a now points to where b is pointing.
Note: Keep in mind that now when you have both a and b pointing to the same memory location, if you use either delete []a or delete []b, memory location pointed to by both a and b will be cleared.
Imho a lot of confusion can be avoided when you think of delete as not acting on the pointer, but on the object it points to. It is not the pointer that is deleted, but the array. Take this example, which is actually very similar to yours:
struct Foo {
int id;
Foo(int i) : id(i) {}
};
Foo* a = new Foo(1);
Foo* b = new Foo(2);
Foo* c;
c = a;
delete c;
c = b;
delete c;
The only effect delete c; has on c is that we are not allowed to derefernce it afterwards, but what gets deleted is first the Foo object with id 1 and then the one with id 2.
Another way - you can to think about optimizations. Maybe you don't need to allocate memory here.
See this case
int a[5];
int b[10];
int func(int param) {
for (int i = 0; i < 5; ++i){
a[i] = i * i;
}
for (int i = 0; i < 10; ++i){
b[i] = 50;
}
}
int main(){
for (int i = 0; i < 10000; ++i){
func(i);
}
return 0;
}
You don't need to allocate/free memory per iteration. But if you have multithreading, it will be a bit more complicated.
Using similar method I greatly improved the speed of calculations in the project for science.
Your code should be clear for everybody. Think about who will be after you. If the choice between readability and speed - should choose readability.
Is it a thing not do to, or is it right? The fact is to use new many times on one pointer:
double * a;
a=new double (5);
cout<<*a<<endl;
a=new double(10);
cout<<*a;
delete a;
Thanks.
SOLUTION:
So one possible solution is?!
double * a;
a=new double (5);
cout<<*a<<endl;
delete a;
a=new double(10);
cout<<*a;
delete a;
In case we don't know if the pointer a point to empty cell, it's possible to use NULL pointer:
double * a=0;
//... the code use *a to allocate or not some informations
delete a;
// ... the code continues with the possibility of allocate again using *a.
In answer to your follow up question, (how do you make sure you're not deleting a null pointer): It doesn't matter. delete null does nothing.
It's better to write your code in a way that you know the state at any point: only assign pointers once. If you really want to use the idiom in your question, use a smart pointer (which will do the deletion for you as it gets reset or goes out of scope):
std::auto_ptr a;
a.reset(new double(5));
cout << *a << endl;
a.reset(new double(10));
cout << *a << endl;
// no need to call delete at all. std::auto_ptrs destructor will do it for you.
It's not okay - the first allocated memory will leak. But the main reason is that it's not idiomatic C++. What's wrong with plain old
double a;
a = 5;
cout << a << endl;
a = 10;
cout << a;
No, that will cause a memory leak. Every new needs a corresponding delete.
It is OK. Because a pointer can point to what it wants. So a double* p can point to any objects with type double.
However, in your specific situation, it is not perfectly OK, because you have newed a block of memory and then let the pointer change its target. The old 5 memory block has no pointer pointed to and you cannot access it anymore; however it still occupy a block of memory. This is considered as memory leak.
In this case, you may want to use something like
std::shared_ptr<double> p(new(10.0));
and then you can renew it to
p.reset(new(5.0));
Before you do a=new double(10); you need to delete a; first. Otherwise, you'll end up with a small memory leak, seeing as you requested the memory and then never freed it. Your code should look like this:
double *a = new double(5);
cout << *a << endl;
delete a; // note the delete
a = new double(10);
cout << *a;
delete a;