I have a member function that I call, from there I get a pointer to a private member which is of class BankAccount, I am unsure what happens with the pointers when I deallocate them. I create a new pointer and heap memory address but then assign the pointer to something else. What does "delete" end up deleting?
I read that if you delete a pointer
Here is the code
void Employee::raise(){
BankAccount* tempBank = new BankAccount(); //set pointer to new heap place
double amt;
tempBank = get_bank(); // set pointer to existing heap implicitly
amt = tempBank->get_amount();
amt = (amt + (amt/12));
tempBank->set_amount(amt);
delete tempBank; //does this delete new heap created or does it add a new block of
//memory to heap since it is trying to delete a pointer assigned
//by memory address
tempBank = NULL;
}
I realized I could just do the code below to avoid this situation, but now I am curious as to what happens in the above situation with the memory
BankAccount* tempBank = get_bank();
So what exactly happens when delete is called in my original situation?
When you use delete ptr; the object pointed to by ptr is destroyed and the corresponding memory is returned to the memory management system. The variable ptr and any copy thereof hold a bit pattern referring to now inaccessible memory (the system may still allow you to actually access this memory and it may even still contain the original data but that's undefined behavior and you shall not rely on it).
Put differently, the memory deallocation does not affect the pointer but it does affected the pointed to entity. In your case, the BankAccount, i.e., the result of *tempBank gets destroyed while the pointer tempBank remains unchanged by the delete operation. Obviously, setting tempBank to NULL does change this specific pointer but none of the other copies (if any), giving you false sense of security: I'd not set deleted pointers to NULL unless I keep them around for whatever reason...
Pointers are essentially just the address of the first byte in memory that belongs to the data structure they point to. So in your case:
BankAccount* tempBank = new BankAccount(); // this creates a new object of type BankAccount
// the pointer tempBank points to the first byte of that object in memory
tempBank = get_bank(); // now tempBank points to the first byte of whatever is returned from get_bank()
// that means that you no longer know the address of the object you created above (tempBank now points to something different)
// C++ has no garbage collection, so you just leaked that memory
delete tempBank; // you delete the object that was returned from get_bank
// so that memory is now marked as free and can be reused by whatever needs it
tempBank = NULL; // this is good style, you should always do it, but it does nothing to any allocated memory
BTW: using plain new and delete and owning raw pointers is considered bad style in modern C++. YOu might want to consider using std::shared_ptr or std::unique_ptr (or their boost equivalents if you cannot use C++11 yet)
I found this information that may be useful to you:
ordinary delete Deallocates the memory block pointed by ptr (if not null), releasing the storage space previously allocated to it by a call to operator new and rendering that pointer location invalid.
You can find more information in the original url: http://www.cplusplus.com/reference/new/operator%20delete/
delete tempBank;
when delete is called on pointer , it releases memory pointed by that variable[tempBank].
There are two notions of delete in C++: One is the operator, declared as ::operator delete(void*), which basically only frees up the memory and isn't usually thought about by most programmers. The other is the delete expression, delete p;, where p is a T*. The expression invokes the destructor of the object pointed to by p (and then frees the memory), which is a crucial language feature of C++ that has no analogue in C.
Well first of all, you are allocating from heap with your first exp which is
BankAccount* tempBank = new BankAccount();
and you lose the address of it with assigning another object address to tempBank pointer by
tempBank = get_bank();
so actually when you delete tempBank; you actually deleting the object that you allocated in the function get_bank(). Also because you have lost the address of object that you allocated with new BankAccount(), there is no more way to delete it, because you do not know the address of this object.
In your question, Are you sure that get_bank() indeed returns pointer to object allocated on heap (and not address of just plain object on stack). You have not mentioned it clearly hence it's worth to confirm it again. Now, coming back to question, if get_bank() returned pointer to private member which let's say was not on heap - in that case doing doing tempBank will result in undefined behavior because you can only invoke delete on an object which was created using new. But if get_bank() returned pointer to object allocated on heap then it will free memory of that object and then accessing that object from any other member function could become a nightmare!
You can check below link for some more related information,
Calling delete on variable allocated on the stack
Related
I know this is pretty common question, but still new for me!
I don't understand concept of dangling pointer, was googling around, and writing test methods to find one.
I just wonder is this a dangling pointer? As whatever example I found was returning something, here I'm trying something similar!
Thanks!
void foo(const std::string name)
{
// will it be Dangling pointer?!, with comments/Answer
// it could be if in new_foo, I store name into Global.
// Why?! And what is safe then?
new_foo(name.c_str());
}
void new_foo(const char* name)
{
// print name or do something with name...
}
A dangling pointer is a pointer that points to invalid data or to data which is not valid anymore, for example:
Class *object = new Class();
Class *object2 = object;
delete object;
object = nullptr;
// now object2 points to something which is not valid anymore
This can occur even in stack allocated objects:
Object *method() {
Object object;
return &object;
}
Object *object2 = method();
// object2 points to an object which has been removed from stack after exiting the function
The pointer returned by c_str may become invalid if the string is modified afterwards or destroyed. In your example you don't seem to modify it, but since it's not clear what you are going to do with const char *name it's impossible to know it your code is inherently safe or not.
For example, if you store the pointer somewhere and then the corresponding string is destroyed, the pointer becomes invalid. If you use const char *name just in the scope of new_foo (for example, for printing purposes) then the pointer will remain valid.
A dangling pointer is a (non-NULL) pointer which points to unallocated (already freed) memory area.
The above example should be correct given that the string is not modified through new_foo.
Taken from here. Although, even if this is for C, it is the same for C++.
Dangling Pointer
When a pointer is pointing at the memory address of a variable but after some time that variable is deleted from that memory location while the pointer is still pointing to it, then such a pointer is known as a dangling pointer and this problem is known as the dangling pointer problem.
Initially
Later
Example
#include<stdio.h>
int *call();
int main() {
int *ptr;
ptr = call();
fflush(stdin);
printf("%d", *ptr);
return 0;
}
int * call() {
int x=25;
++x;
return &x;
}
Its output will be garbage because the variable x is a local variable. Its scope and lifetime are within the function call hence after returning the address of x variable x becomes dead and the pointer is still pointing to that location.
As a matter of style, I explain a dangling pointer as "a pointer which still exists, even though the object it pointed to no longer exists".
In your case, the pointer name exists for a shorter period that the object that it points to. So it's never dangling.
Inside common C++ classes, pointers dangle for a very short period, inside destructors. That's because the delete statement is before the last } of the destructor, while the pointer itself ceases to exist at the last }. If you don't want to worry about this, use e.g. unique_ptr<T>. The T* pointer will dangle for a very short time inside the unique_ptr::~unique_ptr destructor, which is perfectly safe.
Dangling pointers is a situation where you have valid pointers in the stack, but it is pointing to invalid memory. You might end up in this situation when you deallocate the heap memory before the pointers in stack deallocated.
This is a security issue. Because when you deallocate a memory, we are informing Operating System, that we no longer need this section of memory. So OS will mark that piece of memory as ready to allocate and allocate to other applications when they request for memory.
Usually, in C++, memory allocated and deallocated through a general pattern. Constructor in a class gets invoked when a class initialised and this is the right place to allocate memory in heap.Destructor will be invoked when the class instance goes out of scope, and this is the right place to deallocate memory from heap. Assume we already created a class that does allocation and deallocation of memory in constructor and destructor respectively.
int main() {
SomeClass pointer1 = SomeClass();
SomeClass pointer2 = pointer1;
}
In the above example code, there are two variables declared but both holding the same value. When the constructor invoked, it allocates a heap memory. Then we are declaring one more variable and assigning the same value. In C++ usually, when you assign a value of complex type, it does a shallow copy (unless you explicitly implemented copy constructor) instead of deep copy. That means the only pointer gets copied in Stack, but not the heap memory. Actually it is not recommended to copy heap memory for performance reasons. Now the final memory layout looks like that we have two pointers pointing to the same heap memory.
Now when the function is done with execution, local variables goes out of scope and it invokes destructor. First, pointer2 invokes destructor that deallocates the heap memory. At this point, pointer1 becomes dangling pointer. It points to a memory that is already deallocated.
From this example, we understood that the primary cause of dangling pointer is having multiple owners for the same resource. Because when one pointer deallocates memory other pointers became dangling pointers.
//Declaring two pointer variables to int
int * ptr1;
int * ptr2;
// Allocating dynamic memory in the heap
ptr1 = new int;
ptr2 = ptr1; // Having both pointers to point same dynamic memory location
//deleting the dynamic memory location
delete ptr1;
ptr1 = nullptr;
//ptr2 is still pointing the already deleted memory location
//We call ptr2 is a dangling pointer
Dangling Pointer and dangling pointer problem
If any pointer is pointing the memory address of any variable but after some variable has deleted from that memory location while pointer is still pointing such memory location.
That pointer is called as dangling pointer and the problem that arises at that time is called as dangling pointer problem.
Here are some examples: Dangling Pointer and dangling pointer problem
I have few questions about the placement new while reading the C++ Primer Plus.
The sample code in the book is like this:
class JustTesting{
private:
string words;
int number;
public:
JustTesting(const string & s = "Just Testing", int n = 0){
number = n;
words = s;
//some code here
}
~JustingTesting(){}
};
char * buffer = new char[BUF]; //get a block of memory
JustTesting *pc1, *pc2;
pc1 = new (buffer) JustTesting; //Place object in buffer
pc2 = new JustTesting("Heap1",20); //Place object on heap
//some code
JustTesting *pc3, *pc4;
pc3 = new (buffer) JustTesting("Bad Idea", 6);
pc4 = new JustTesting("Heap2", 10);
//some code
delete pc2; //free Heap1
delete pc4; //free Heap2
pc3->~JustTesting(): //Does the order of these two destructor call
pc1->~JustTesting(); // matters?
delete[] buffer; //free buffer
The author says, we cannot use
delete pc1;
or
delete pc3;
to delete the objects they pointing to, because delete works in conjunction with new but not with placement new. For example, the pointer pc3 does not receive an address returned by new, and delete pc3 will result in a runtime error.
The questions are:
first, will the object pointed to by pc3 overwrite the one pointed to by pc1? If no, how could two different objects stay in a same address. If yes, why we still possible to call the destructor explicitly(pc1->~JustTesting();) to free the object's memory.
question two: Does the order of these two explicit destructor call matter?
question three: What is the meaning of "the pointer pc3 does not receive an address returned by new"? Is the address returned by new different with the address given by assignment?
Thank you!
Everything is right, until...
pc3 = new (buffer) JustTesting("Bad Idea", 6);
This invokes undefined behaviour (no?). You've already constructed an object of type JustTesting at buffer, but you have not destructed it! At the same time, you're creating yet another object at the same location. Then, the first object becomes corrupted (althought, in standardese minds, it still exists in a parallel universe).
You can't perform delete on a pointer to anything that hasn't been allocated (and constructed) by operator new. Similarly, you can only destroy and deallocate an array created by operator new[] with operator delete[].
Now, "placement new" is just a fancy name for a direct call to a constructor. Thus, new(buff) Type(...) is just a call to Types constructor with this set as buff. And, simmetric with what said above, you can only destroy what has been constructed.
If you use automatic storage, operator new, or whatever other implicit-RAII-conformant means that is responsible for allocating, constructing, and destructing your objects automatically (or when you specify it shall be done), then calling an object's destructor in such a context will lead to the destructor being called twice, a.k.a undefined behaviour.
Now, it happens that you (shall I repeat it again? you!) are the one who decides when and how to obtain the memory for the object, then the environment has no change of guessing when to either destroy or deallocate the object. Thus, once you call the object's destructor explicitly, the memory that once contained it is under your responsibility for being freed, somehow, if at all.
Think of it as such. An expression of the form ptr = new X(...) can be perfectly implemented as...
ptr = malloc(sizeof(X));
new(ptr) X(...);
And operator delete becomes...
ptr->~X();
free(ptr);
The questions are: first, will the object pointed to by pc3 overwrite the one pointed to by pc1?"
This is dangerous, both objects will be attempting to share the same block of memory.
If yes, why we still possible to call the destructor explicitly(pc1->~JustTesting();) to free the object's memory.
This does not free the memory of an object created via placement new. It simply calls the destructor of the object. The conventional delete operator will call the destructor, then attempt to free the memory by assuming it was allocated normally. In this example, it will effectively try to call a destructor on that block of memory twice, due to the sharing issue that has already been raised.
question two: Does the order of these two explicit destructor call matter?
No, in either case, the second call is likely to have issues.
question three: What is the meaning of "the pointer pc3 does not receive an address returned by new"? Is the address return by new different with the address given by assignment?
The address returned by new is a block of freshly allocated memory from the heap (assuming the default new operator hasn't been overridden). The address returned by placement new is simply the address of the block of memory you gave to it.
first, will the object pointed to by pc3 overwrite the one pointed to by pc1?
Yes. They will both be stored at the address pointed to by for buffer. This may be undefined behaviour, and is generally a bad idea anyway (unless you know for sure that the class's destructor doesn't do anything important).
If yes, why we still possible to call the destructor explicitly(pc1->~JustTesting();) to free the object's memory.
Most likely, pc1 and pc3 point to the same location. I'm not sure if that's guaranteed, but I can't imagine why it would not be the case on any implementation.
If pc1 and pc3 point to the same location, then this question is like asking why the following code works:
char *p1 = new char[50];
char *p2 = p1;
delete [] p2;
What is the meaning of "the pointer pc3 does not receive an address returned by new"? Is the address return by new different with the address given by assignment?
Bad wording probably. Clearly pc3 does receive an address returned by new - you can see it right there in the code:
pc3 = new // ... other stuff ...
I suspect they mean that the address was not allocated by new. Normally new allocates a block of memory to hold an object, and then constructs an object in that memory block. With placement new, it only constructs an object in the provided memory block.
Likewise, delete will destroy the object whose pointer was passed to it, and then free a memory block that was previously allocated at that address. deleteing an object not allocated with new is undefined behaviour - think of JustTesting a("Object on stack", 30); delete &a;.
If you're lucky, delete pc3 might have the same effect as pc3->~JustTesting(); delete [] buffer;, so it might not crash - although then delete [] buffer; would crash later since you're deleting an object twice. You definitely should not rely on that. The only safe thing to do is to not delete the objects allocated with placement new.
The questions are: first, will the object pointed to by pc3 overwrite the one pointed to by pc1?
Yes.
If yes, why we still possible to call the destructor explicitly(pc1->~JustTesting();) to free the object's memory.
pc does not already exist, any function invoking on it is UB.
question two: Does the order of these two explicit destructor call matter?
You shouldn't call them together at all.
question three: What is the meaning of "the pointer pc3 does not receive an address returned by new"? Is the address returned by new different with the address given by assignment?
I think it should mean "the pointer pc3 does not receive an address returned by newly allocated". The placement new just return the address you passed to it.
This question already has answers here:
Pointers in c++ after delete
(3 answers)
Closed 5 years ago.
void doSomething()
{
TheObject *ptr = new TheObject;
delete ptr;
ptr = NULL;
return 0;
}
Let me borrow the words from operator delete in cplusplus.com:
Deallocates the memory block pointed by ptr (if not null), releasing
the storage space previously allocated to it by a call to operator new
and rendering that pointer location invalid.
Please help to clear my confusions: what happens to the pointer itself after delete? The pointer itself does have an address, right? So after the pointed block is deleted, what about the pointer itself?
Could I say that the pointer itself will be free after returning the method where the pointer is initialized? Is the pointer itself placed on the stack or heap?
The pointer itself does have an address and the value. The address of the pointer does not change after you perform delete on it. The space allocated to the pointer variable itself remains in place until your program releases it (which it might never do, e.g. when the pointer is in the static storage area). The standard does not say what happens to the value of the pointer; all it says is that you are no longer allowed to use that value until you assign your pointer a valid value. This state of the pointer is called dangling.
In your program, the pointer ptr is dangling after delete has completed, but before the ptr = NULL assignment is performed. After that it becomes a NULL pointer.
The pointer it self is placed on stack or heap?
Pointer variable is a regular variable. Its placement follows the same rules as the placement of other variables, i.e. you can put a pointer in a static area, in an automatic area (commonly known as "the stack") or in the dynamic memory (also known as "the heap"). In this case, you allocate a pointer to a pointer:
TheObject **ptrPtr = new TheObject*; // The pointer to a pointer is on the stack
*ptrPtr = new TheObject; // The pointer to TheObject is in the heap
delete *ptrPtr; // The space for TheObject is released; the space for the pointer to TheObject is not
delete ptrPtr; // Now the space for the pointer to TheObject is released as well
// The space for the pointer to pointer gets released when ptrPtr goes out of scope
In C and C++, a pointer can be thought of in many ways as just an integer in disguise. So when you say:
TheObject *ptr = new TheObject;
Then ptr is just like a stack-allocated ("automatic") integer variable, one that happens to be big enough to hold the memory address of the heap-allocated TheObject. It's similar to saying
size_t i = /* some value given to you by the runtime */.
Later on, when you write
ptr = NULL;
it has an identical meaning to:
i = 0;
So what happens to the pointer when you leave the function? Just as with any other automatic variable, it's deallocated at the end of the block. It's as simple as that. (Of course, the thing that's pointed to will live on until you call delete, or free() in C.)
Performing delete invalidates the pointer (see [new.delete.single]#10). It could be said that the value is changed: previously it had a value, but now it does not have a value.
Trying to read the value of the pointer (note: this is different to dereferencing it) causes implementation-defined behaviour since C++14, which may include generating a runtime fault. (In C++11 and older standards, it was undefined behaviour). Ref: [basic.stc.dynamic.deallocation]#4.
It would be legal for the compiler to also set the pointer to be null, or set it to some recognizable garbage for debugging purposes (although I don't know of any compilers that do this).
I am new to C++, and now am studying new and delete keywords.
Point ppaa = *new Point;
Point *p = &ppaa;
ppaa.xpos = 1;
ppaa.ypos= 3;
delete &ppaa;
delete p;
Could you please explain why I cannot delete the ppaa above using &ppaa?
I know that delete can only operate on pointer, but I cannot understand why above is not possible since they are actually memory locations. Searching similar questions, it seems that this is related to the copying operations that happen at the first line, but I do not have good explanations.
T t = x;
is known as Copy Initialization. It:
It tries to convert x to an object of type T &
Then copies over that object into the to-initialized object t.
So your code statement,
Point ppaa = *new Point;
Creates a Point obejct on freestore/heap and
then copies that object to create a stack object ppaa.
Both these objects are different objects.
As you can see, You do not have any pointer to the heap object anymore after executing this statement.
You need to pass the address returned by new to delete in this case, Since you do not have the address anymore it results in memory leak.
Further, Note that &ppaa does not return the address returned by new it returns the address of the object ppaa located on the stack. Passing this address to delete results in Undefined Behavior because ppaa was never allocated on freestore/dynamically it is a stack based local/automatic object.
I know from reading parashift.com that using delete on a pointer frees the memory
[16.1] Does delete p delete the pointer p, or the pointed-to-data *p?
The pointed-to-data.
The keyword should really be delete_the_thing_pointed_to_by. The same
abuse of English occurs when freeing the memory pointed to by a
pointer in C: free(p) really means free_the_stuff_pointed_to_by(p).
And the wiki article on "delete (C++)" says "many programmers set the pointer to NULL afterwards to minimize programming errors"
Is it necessary to think about deleting the pointer itself?
Is it correct to say that a declared pointer still takes up memory?
i.e. if I were to declare billions of different pointers to NULL, it would still use up memory (and hence I would have a need to delete the pointer itself).
How would I delete the pointer?
Usually the pointer will stop existing at the end of the scope.
Example:
{
int *p = NULL;
// do something with p
} // <-- p will be destroyed here
Hereby the pointer variable is said to have automatic storage duration. If done consistently, assigning 0, or NULL, or nullptr to a pointer variable that doesn't point to an object of the specified type has the advantage that one can easily recognize whether or not it's safe to dereference the pointer. This practice has no direct connection to the lifetime of the pointer or the previously pointed to object (if any).
In contrast, when you have the following code:
{
int *p = new int;
// do something with p
//delete p; // <-- the object p points to will not be destroyed unless it's deleted
} // <-- p will be destroyed here
Again, the pointer variable itself will be destroyed at the end of the scope, because it has automatic storage duration.
In contrast, the int object, which we have allocated using the new operator, to which the pointer points in this example, has dynamic storage duration. It will continue to reside in memory until delete is called to free it. This may result in a memory leak (if you lose any reference to the object p pointed to, as in this example).
Of course, if the pointer is dynamically created by itself, e.g., as in
{
int** p = new int*;
// do something with p
//delete p; // <-- the object p points to will not be destroyed unless it's deleted
} // <-- p will be destroyed here
... this could be the starting point for a recursive example.
Note that there is a thing called static storage duration, which means the variable will exist until the end of the program (e.g., global or static variables). If you want to read up more on this topic see:
http://en.cppreference.com/w/cpp/language/storage_duration
http://en.cppreference.com/w/cpp/language/static
Note that independent of its storage duration, any variable (including pointers) takes up some amount of memory. Generally, if you allocate space for too many objects at the same time you will run out of memory. Therefore, you should avoid implementing things like infinite recursion, fork bombs, memory leaks, or alike.
Is it necessary to think about deleting the pointer itself?
It is only necessary if the pointer itself has no automatic memory management. That is, if storage for the pointer itself was allocated with new or malloc.
Is it correct to say that a declared pointer still takes up memory?
A pointer takes up memory, it has to be stored somewhere in order to be used, right?
if I were to declare billions of different pointers to NULL, it would still use up memory (and hence I would have a need to delete the pointer itself).
Of course it would use up memory, billions * sizeof(void*). Needing to delete the pointer has nothing to do with it taking space or not, everything takes space (well, almost, there are some special optimizations); you only need to delete what was allocated with new.
How would I delete the pointer?
How was it allocated? If it has automatic storage then its memory will be automatically freed when the pointer goes out of scope. If it was allocated with new it has to be deleted with delete, same for new[]/delete[] and malloc/free.
1) Usually a pointer is on the stack or a member of another class and you wouldn't need to worry about deleting such pointer.
2) Yes.
3) Yes, they would use up memory and you would need to release the pointer.
4) Either let a local pointer fall out of scope, or get rid of whichever object contains it.
Finally note that raw pointers are quite out of favor. Prefer either an appropriate container such as vector, or as needed an appropriate smart pointer.
A declared pointer takes up memory on the stack and will be deleted when it goes out of scope. This is the same process that takes place with primitive types. You do not need to worry about memory management for anything on the stack.
The new operator on the other hand allocates memory on the heap, and must be explicitly deleted with delete.
Is it necessary to think about deleting the pointer itself?
it depends on how the pointer was created. if you create a pointer on the stack:
void func(void) {
int* p;
...
}
you should delete the memory pointed to by p (when it makes sense), but p is simply an auto variable which will be "deleted" when the stack is unwind;
Is it correct to say that a declared pointer still takes up memory?
i.e. if I were to declare billions of different pointers to NULL, it would still use up memory (and hence I would have a need to delete the pointer itself).
of course it does... a pointer is just a location in memory containing an address into the virtual memory; in fact doubling the virtual memory space will double the space your pointers occupy (but not necessarily the space occupied by the data they point to).
How would I delete the pointer?
as I said, it depends on how you created the pointer. if you for some reason allocated it on the heap, then you should free that memory as well.
A pointer is simply a variable, like an int. On a 32-bit CPU a pointer will consume 4 bytes of storage, 8 bytes on a 64-bit system.
So if you declare a billion pointers to NULL, you have essentially declared a billion *int*s.
The thing that makes it a pointer is only the fact that the value stored in that variable just happens to be the address of some place in memory. When you call delete on a pointer, you are freeing the memory at that address stored in the pointer, not the memory used by the pointer variable itself.
You can not delete the pointer itself - only pointed by it data.
Pointer is destroyed when its scope is ended:
{
int *p = NULL;
}
After closing bracket the pointer is distroyed.
The question is what is deleting a pointer. If you assign new pointer to the same variable you don't need to worry about deleting billions. If you allocate space for pointer, you surely should delete them, but then again it will be pointer to pointers, so it's pointers, not pointer that is getting deleted. If you allocate space statically (like declaring array of billions of pointers) you can't really delete it.
In short, I think you need a better understanding of the nature of pointer.