Deleting Pointers???

Started by
12 comments, last by Zahlman 13 years, 3 months ago

Hi,

I have been thinking about using pointers to variables and instances of classes/structs, but I am not sure of something. If I am using a variable and declare a pointer to it, does deleting the pointer and making it 'null' also delete the variable?

Here is an example:

int x = 5;int* pointer = &x;//Work with variable until//I don't need it anymore, then:delete pointer;pointer = 0;


I am not sure what happens here - after this code has been executed, does the variable "x" still exist?
Or to be able to delete a pointer does it have to "not have its own variable" - like this:

int* pointer = new int;//Instead of using a variable name, I//would access it as:*pointer = 5;//And then delete it:delete pointer;pointer = 0;


I do know that after doing this, the memory used to store the value 5 is returned to the "heap", but is it possible to do this with class instances?

Thanks, any help would be greatly appreciated...
Advertisement
The first code snippet is a no-go! Only memory allocated by new has to be deleted, or else you'll end up with some memory corruption. However, it is no problem to set a pointer to the address of any variable, even if not allocated by new.
Quote:
I do know that after doing this, the memory used to store the value 5 is returned to the "heap", but is it possible to do this with class instances?


Short answer: Yes.

Just put the name of it in there:
SomeClass* pointer = new SomeClass;
Just to clarify what seems to be the central misconception leading to your question: you don't delete a pointer. You delete the value of a pointer, i.e. you delete the memory that the pointer is pointing to.

With that in mind, haegarr's post should be much clearer.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Thanks haegarr and ApochPiQ - after I posted that, I realized it was incorrect.

But if I allocate memory for an instance using new...
class MyClass {public:   int number;   int array[2];};int main() {   MyClass* instance = new MyClass;   //Is this the correct way to access members?   *instance.number = 5;   *instance.array[0] = 1;   *instance.array[1] = *instance.number;   delete instance;   instance = 0;}

So, yeah.... is that the way to access members variables?
If so, that also how to access member functions?
http://www.gamedev.net/community/forums/topic.asp?topic_id=591367

3rd post.

Simple answer , use -> operator.

And, a bit about your original question (if I understand it correctly):

There are two types of memory: the heap and the stack.

You allocate variables from the heap by using the new operator and release them with delete.

You "allocate" variables from the stack by simply declaring them and you don't release them, they are released automatically when they go "out of scope".

So, modifying your code a bit:
int* pointer;   //pointer is actually a variable allocated from the stack of type int*pointer = new int; //now you allocate some memory from the heap ( 4 bytes) and keep the address in the pointer variable//Instead of using a variable name, I//would access it as:*pointer = 5; //you're writing the value 5 at the address kept in the pointer variable//And then delete it:delete pointer; //you release the heap memory allocated earlierpointer = 0;    // you set the value of the pointer stack variable to 0. it's not required to delete the memory alocated, you did this in the previous line, but it's a good thing to do.


If the previous code were the entire body of a function, at the end of the function, the compiler would have inserted code that would release the stack space allocated for the pointer variable.
Quote:is that the way to access members variables?
You can do it that way (although you might need some parentheses - can't remember for sure off the top of my head). However, it's more typical to use the -> operator, e.g.:
instance->number = 5;
Quote:If so, that also how to access member functions?
Yup.

Also, even though what you have there is probably just intended as an example, keep in mind that in C++ you should generally only create objects using new if you have a specific reason for doing so. In other words, prefer this:
MyClass instance;
Over this:
MyClass* instance = new MyClass;
(Oh, and the usual admonition: Once you have a better idea of how memory management in C++ works in general, use RAII containers where appropriate rather than doing manual clean-up as you are currently.)

[Edit: One more note - since the variable instance will go out of scope when main() exits, you don't need the line 'instance = 0;' at the end of your main() function.]
One more thing: even though they are usually used together, pointers and new/delete operators are not tied together.

So, take for example the following code (don't take it as an good example, as it contains bad code, only take it as "it can be done").

void aFunction(){    new int; //we allocate an integer from the heap    int* pOne = new int;    int* pTwo = pOne;  //pTwo actually point at the same place in memory as pOne    *pOne = 1;        //and, because of that, *pTwo is 1 as well   for(int i=0;i<10;++i)   {      if(i%2==0)         *pOne++      else         (*pTwo)++;   }   // now, you'd think that because, at the beginning of the for loop, the pOne and pTwo pointed at the same place in heap   //and the loop runned for 10 times, both pOne and pTwo would still point to the same place in memory,and the value of both *pOne and *pTwo is 11   //but this in not it. *pTwo is 6 and *pOne is... we don't know   delete pOne;     //this is bad, really bad   delete pTwo;     //this releases the heap allocated by the line int* pOne = new int;    delete new int;  //an pathetic attempt to release the heap memory allocated by the first line of this function (new int;)}


Now, what happened is as follows:

The line (*pTwo)++ does what we're expecting of it and that is increases by one the value stored on the heap that the pTwo pointer points at. But *pOne++, due to the order the operators are evaluated, first increases the value of pOne (the value of the pointer itself) by evaluating pOne++ and then, using the new value of pOne, returns whatever value is stored on the heap in the location that the pOne pointer now points, by evaluating the * operator. That is why, after the for loop, *pTwo still points to the variable we allocated on the heap and that has the value increased 5 times (so now it's 6) and pOne points to somewhere else in the memory.

Also, please note that, no matter how many pointers you have pointing at the same place in memory, you only need to release the memory once and take care not to use the pointers with that value anymore, as this will still access the old location of the heap which may now be used by the computer for something else.

One more thing: the first line of the function

new int;

does what it is supposed to do: allocated the memory to hold an integer value from the heap and returns the location of that variable to the program. However, since you are not storing it in any pointer, the value of the location (the memory address) is lost, so you cannot release the memory allocated. It will remain there alocated forever (untill your program ends). It is called a memory leak;

the last line of the function, no matter how weird, is valid

delete new int;

what it does is first allocate a new int from the heap, return the address of that variable to the expresiion, which the delete operator then uses to release that memory that we just allocated. It's valid, though silly. (if instead of int we had a class in there, both the constructor and the destructor of that class would have runned in that line).


Quote:keep in mind that in C++ you should generally only create objects using new if you have a specific reason for doing so.
Well I see now, but if memory is returned when variables go out of scope, what is the use of allocating memory in the first place? When would I have a specific reason for allocating using new/delete?
Quote:Original post by BioProton
Quote:keep in mind that in C++ you should generally only create objects using new if you have a specific reason for doing so.
Well I see now, but if memory is returned when variables go out of scope, what is the use of allocating memory in the first place? When would I have a specific reason for allocating using new/delete?
For example when
* the lifetime of the allocated object is independent on (especially longer as) the surrounding environment (be it the scope of a routine body or an object holding the pointer), or
* the allocated memory is too big to be stored on the runtime stack.

This topic is closed to new replies.

Advertisement