c++ Do Local variables, with reserved memory, need to be freed? - c++

I've a simply question.
I have been looking for the answer but I might not found the correct tags or words to find the solution...
The question is, as the title says: Do local variables (which have reserved memory) need to be freed? I meant, for example, if I've got the following function:
myClass* myFunction(){
myClass* A = new myClass;
return A;
}
In case of "yes", where Should I call "delete"? both before and after "return" are nonsense...
Am I right?

Don't use new unless you need to.
This avoids new, and so doesn't need deleting
myClass myFunction(){
myClass A;
return A;
}
If you think you need pointers, consider using smart pointers.
If you want the excitement of raw pointers, this function returns a raw pointer to the caller, and they must delete it when they are done.
myClass * myFunction(){
myClass * A = new myClass;
return A;
}
myClass * thing = myFunction();
//stuff, that might throw an exception, so watch it
// smart pointers FTW
delete thing;

Assuming that your type is defined something like this:
class myClass { /* ... */ };
Your example is not proper C++ (unless you have a myClass* conversion constructor, which you probably don't).
You do not have to new an object that sits on automatic memory:
myClass myFunction(){
myClass a;
return a;
}
When newing an object on dynamic memory, you can then put it into a pointer variable in automatic memory:
myClass* myFunction(){
myClass* a = new myClass;
return a;
}
Here, a might leak, if it isn't freed by the caller.

Presumably, unless you're doing some interesting operator overloading, you mean to assign new myClass to a pointer and return the pointer
myClass *myFunction(){
myClass *A = new myClass;
return A;
}
If that is the case, then yes, you will have to delete it at some point. It will be up to the caller of this function to keep the pointer and delete it when appropriate.
Alternatively you can use smartpointers.

Use shared_ptr instead of raw pointers.
std::shared_ptr<myClass> myFunction()
{
std::shared_ptr<myClass> A = std::make_shared<myClass>(constructor parameters, if any);
return A;
}
void f()
{
std::shared_ptr<myClass> A = myFunction();
}
This will emulate Java-style garbage collection.

Related

Getting data out of C++ structs and pointers [duplicate]

In C++ do you always have to initialize a pointer to an object with the new keyword?
Or can you just have this too:
MyClass *myclass;
myclass->DoSomething();
I thought this was a pointer allocated on the stack instead of the heap, but since objects are normally heap-allocated, I think my theory is probably faulty?
Please advice.
No, you can have pointers to stack allocated objects:
MyClass *myclass;
MyClass c;
myclass = & c;
myclass->DoSomething();
This is of course common when using pointers as function parameters:
void f( MyClass * p ) {
p->DoSomething();
}
int main() {
MyClass c;
f( & c );
}
One way or another though, the pointer must always be initialised. Your code:
MyClass *myclass;
myclass->DoSomething();
leads to that dreaded condition, undefined behaviour.
No you can not do that, MyClass *myclass will define a pointer (memory for the pointer is allocated on stack) which is pointing at a random memory location. Trying to use this pointer will cause undefined behavior.
In C++, you can create objects either on stack or heap like this:
MyClass myClass;
myClass.DoSomething();
Above will allocate myClass on stack (the term is not there in the standard I think but I am using for clarity). The memory allocated for the object is automatically released when myClass variable goes out of scope.
Other way of allocating memory is to do a new . In that case, you have to take care of releasing the memory by doing delete yourself.
MyClass* p = new MyClass();
p->DoSomething();
delete p;
Remeber the delete part, else there will be memory leak.
I always prefer to use the stack allocated objects whenever possible as I don't have to be bothered about the memory management.
if you want the object on the stack, try this:
MyClass myclass;
myclass.DoSomething();
If you need a pointer to that object:
MyClass* myclassptr = &myclass;
myclassptr->DoSomething();
First I need to say that your code,
MyClass *myclass;
myclass->DoSomething();
will cause an undefined behavior.
Because the pointer "myclass" isn't pointing to any "MyClass" type objects.
Here I have three suggestions for you:-
option 1:- You can simply declare and use a MyClass type object on the stack as below.
MyClass myclass; //allocates memory for the object "myclass", on the stack.
myclass.DoSomething();
option 2:- By using the new operator.
MyClass *myclass = new MyClass();
Three things will hapen here.
i) Allocates memory for the "MyClass" type object on the heap.
ii) Allocates memory for the "MyClass" type pointer "myclass" on the stack.
iii) pointer "myclass" points to the memory address of "MyClass" type object on the heap
Now you can use the pointer to access member functions of the object after dereferencing the pointer by "->"
myclass->DoSomething();
But you should free the memory allocated to "MyClass" type object on the heap, before returning from the scope unless you want it to exists. Otherwise it will cause a memory leak!
delete myclass; // free the memory pointed by the pointer "myclass"
option 3:- you can also do as below.
MyClass myclass; // allocates memory for the "MyClass" type object on the stack.
MyClass *myclassPtr; // allocates memory for the "MyClass" type pointer on the stack.
myclassPtr = &myclass; // "myclassPtr" pointer points to the momory address of myclass object.
Now, pointer and object both are on the stack.
Now you can't return this pointer to the outside of the current scope because both allocated memory of the pointer and the object will be freed while stepping outside the scope.
So as a summary, option 1 and 3 will allocate an object on the stack while only the option 2 will do it on the heap.
if you want to access a method :
1) while using an object of a class:
Myclass myclass;
myclass.DoSomething();
2) while using a pointer to an object of a class:
Myclass *myclass=&abc;
myclass->DoSomething();
If you have defined a method inside your class as static, this is actually possible.
class myClass
{
public:
static void saySomething()
{
std::cout << "This is a static method!" << std::endl;
}
};
And from main, you declare a pointer and try to invoke the static method.
myClass * pmyClass;
pmyClass->saySomething();
/*
Output:
This is a static method!
*/
This works fine because static methods do not belong to a specific instance of the class and they are not allocated as a part of any instance of the class.
Read more on static methods here: http://en.wikipedia.org/wiki/Static_method#Static_methods
Simple solution for cast pointer to object
Online demo
class myClass
{
public:
void sayHello () {
cout << "Hello";
}
};
int main ()
{
myClass* myPointer;
myClass myObject = myClass(* myPointer); // Cast pointer to object
myObject.sayHello();
return 0;
}

(C++) How to pass around a pointer to an object allocated with 'new' from function to function without causing a mem leak?

I am working on a project meant to understand memory management using C++,
Inside a function, if I create a new array of Student objects, do function stuff, and then return a pointer to the array like so:
int main(){
Student *ptr = new newStudents[50];
Student p.FunctionCall(ptr);
//stuff
delete[] ptr;
return 0;
}
I will then instantiate the object (make a copy) in main, and other class methods perhaps too, taking care to call delete[] after every usage.
Will it cause a memory leak to pass the heap pointer from function back into main and or other funcs as long as I remember to call delete from the last place it existed?
Constraints: no smart pointers, no namespace and no C++ 11 or higher.
It's for an assignment. All help appreciated.
Correct syntax would be:
MyClass* function(const char* file) {
MyClass *x = new MyClass[50]; //class_type* array_name = new class_type[amount];
//stuff to parse values and then instantiate my classes
return x; // return x directly as a pointer..
}
First.. Do NOT dereference the pointer you got from new and return it, because it's not a pointer to a pointer or pointer to an instance. It's literally a pointer to memory of an array and by dereferencing it, you will be returning an instance and losing the rest.. resulting in a leak.
So with that your of the way, you can now do:
int main()
{
MyClass* array = function("some_file.txt");
// do something with the array above..
delete[] array; //clean up..
}
Yes.
char* allocate_buffer() {
return new char[10];
}
int main() {
auto buf = allocate_buffer();
delete [] buf;
}
No memory leaks. You should use std::array or std::vector instead of managing memory manually.

problems understanding difference between double and single pointer memory allocation in C++

Ok, here i have 2 simple C++ examples, the first one is:
MyClass
class MyClass
{
private:
int test;
public:
int member(){
test = 456;
return 1;
} // one public function
};
global function definition
int funct(MyClass** obj)
{
*obj = new MyClass();
int c = (**obj).member();
return 1;
}
main
...
MyClass* object;
int i = funct(&object);
...
while in the second case, i modify the main like this:
MyClass** object = (MyClass **)malloc(sizeof(MyClass));
int i = fun(object);
Both examples work fine, but i'm not sure if i understood correctly why ONLY in this second case i need a malloc (otherwise it wouldn't compile at all).
Thanks in advance for your help
PS: i know double pointers are more C-style programming, but i'm currently experimenting with both languages.
MyClass** object = (MyClass **)malloc(sizeof(MyClass));
actually this is wrong, malloc will return pointer to allocated memory: MyClass *, so if you later do: *object and would like to see a pointer to MyClass you will be wrong. You should rather:
MyClass* pobject = (MyClass *)malloc(sizeof(MyClass));
MyClass** ppobject = &pobject ;
your question is unclear to me - sorry,also it is not wise to allocate clases with malloc - your one looks like its POD - so it seems to be safe, but I would check it with std::is_pod.
[edit]
working example is below. You asked why you need initialization of object in the second case, thats because in first case you reserve storage for your pointer by simply defining pointer variable : MyClass* object;. Here object can be safely used in funct. In second example, you dont have reserved memory (in this case space on stack) for your pointer to MyClass, so you must allocate it with malloc or new. Hopefully thats clear enough.
MyClass** object = (MyClass **)malloc(sizeof(MyClass*));
//MyClass** object = new MyClass*;
int i = funct(object);
delete *object;
free(object);
//delete object;
First of all, you have a bug (and the whole thing works only because sizeof(MyClass)>=sizeof(MyClass*)):
MyClass** object = (MyClass **)malloc(sizeof(MyClass));
is incorrect, should be
MyClass** object = (MyClass **)malloc(sizeof(MyClass*));
or
MyClass** object = new MyClass*;
Second, you do need malloc() (or new) because you need your double pointer MyClass** to point to some instance of MyClass*. Your first and second (after correction) example differ only in a way where you get this MyClass* - in first example it is on-stack, in second example it is on heap.
Oh, and when it on heap, you need to manually call free() (if malloc() was used to allocate it) or delete (if new was used) for the pointer.
I deleted my previous answer. This is how you should go about initializing the double pointer:
MyClass** object;
object = new MyClass*;
int i = funct(object);
The second line allocates a new pointer to an instance of MyClass, and the call to funct allocates an actual object of MyClass. After this call, object will point to a valid pointer to a valid instance of MyClass.

C++, will this cause memory leak?

I know that I can't get a reference of a local var. such as:
int& func1()
{
int i;
i = 1;
return i;
}
And I know that this is correct, but I have to delete it after calling func2()
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
int main()
{
int *p = func2();
cout << *p << endl;
delete p;
return 0;
}
If the function is like this:
MyClass MyFunction()
{
return new MyClass;
}
MyClass's whole definition is:
class MyClass
{
public:
MyClass() : num(1){}
MyClass(MyClass*) : num(10){}
int num;
};
Will this cause memory leak?
How should I avoid it?
the function returns an object not a pointer, so how can I delete it?
PS: the code comes from the book "Ruminations on C++" Chapter 10.
the original code is:
Picture frame(const Pictrue& pic)
{
// Picture has a constructor Picture(*P_Node)
// Frame_Pic derives from P_Node
// So the constructor Picture(*P_Node) will implicitly convert Frame_Pic to Picture.
return new Frame_Pic(pic);
}
MyClass MyFunction()
{
return new MyClass;
}
This is actually wrong.you are returning a pointer .
so it should be
MyClass* MyFunction()
if your function is as i mentioned above and if you are not deleting it after using it.it will leak memory.
How should I avoid it? the function returns an object not a pointer, so how can I delete it?
that is a compilation error.so the point of deleting it will not rise
If you delete the pointer returned from the funciton there is no memory leak. However this is error prone since it means that every client of the function must know that it should delete the return value. It's much better style to use a smart pointer (either shared_ptr or unique_ptr according to semantics).
The same goes to the Picture example. If this object correctly manages its resources (i.e. deletes in the destructor and has a good copy constructor and operator= (in accordance with the Rule of Three), then there is no memory leak.
With your updated MyClass that has the pointer constructor, I suppose you should write:
MyClass MyFunction() {
MyClass *ptr = new MyClass;
MyClass retval(ptr);
delete ptr; // the dynamically-allocated object isn't needed any more
return retval;
}
That happens to be exception-safe, since the constructor of MyClass can't throw, but as a general rule you really shouldn't ever call new without putting the result straight into a smart pointer:
MyClass MyFunction() {
std::unique_ptr<MyClass>(new MyClass);
return MyClass(ptr);
}
It's a fairly absurd situation anyway - if you're going to return by value, there's no reason to call new at all:
MyClass MyFunction() {
MyClass tmpvalue;
return &tmpvalue; // doesn't actually return the pointer, just an object
// constructed from it
}
And since the value of the pointer isn't even used by the pointer constructor, you could just as well write:
MyClass MyFunction() {
return 0; // returns an object constructed from a null pointer
}
In the original code your quote from the book, I guess that the class Picture has a data member of type P_Node*, in which it stores the pointer value, and calls delete on that pointer in its destructor. Hopefully the author also does something about the copy constructor and copy assignment operator of Picture, to prevent a double-free after the copy. I don't have the book, so I can't check my guess, but the code for Picture should show how it's done.
[Edit: oh, that's one of the books by Koenig and Moo. They are (more than) competent, so pretty certainly their Picture class handles the resource correctly. If it doesn't, it's because it's a deliberate example of Doing It Wrong.]
It's the same as your "func2" example. who ever call "frame" need to free the returning Picture in the end.
MyClass MyFunction()
{
return new MyClass;
}
is incorrect, because operator new returns a pointer to MyClass, but your function returns MyClass, not MyClass*
A simple check would be this:
If you're using N number of new in your program, then you've to use N number of compatible1 delete in your program to avoid memory leak2.
So are you doing that? Yes, in the first case (in which you're doing new int) you're doint that. There is no memory leak.
And rest of the post isn't clear enough to me!
1. By compatible delete, I mean if you're using new in the form of ptr = new T[M], then the compatible delete should be of the form of delete []ptr. Similarly, delete ptr is compatible with ptr = new T.
2. Of course, if you're using some smart pointers, then you don't have to use delete explictly.

Exception Handling Code Please explain it

Please see the following code and its output - please explain me the code
void abc(int);
class A
{
public:
A()
{
cout<<"Constructor Called";
}
~A()
{
cout<<"Destructor called";
}
};
int main()
{
try
{
abc(-1);
}
catch(int p)
{
cout<<p<<endl;
}
return 0;
}
void abc(int p)
{
A * Aptr = new A[2];
if(p<0)
throw p;
}
Output:
Constructor Called
Constructor Called
-1
can anyone explain why is the destructor not being called as in the case of normal stack unwinding
This pointer:
A * Aptr = new A[2];
is a raw pointer. When it goes out of scope only the pointer itself is destroyed - nothing is done to the array it points to. So the array is not delete[]'ed and the destructors are not called. It's a typical example of a memory leak.
There're three typical solutions to the problem:
allocate the array itself on stack
use std::vector
use a smart pointer (not std::auto_ptr - it is not suitable for using with arrays.
The destructor is not called because the objects you allocate are never deleted. You would get the same output if you removed the throw.
If, on the other hand, you changed your function into this:
void abc(int p)
{
A A_array[2];
if (p<0)
throw p;
}
You would see that the destructor was called.
As mentioned elsewhere, C++ pointers do NOT delete the memory they point to when going out of scope. You have a few options:
The hard way - try and do the memory management yourself. This way lies memory leaks and buffer overflows. Try not to do this.
void abc(int p)
{
A * Aptr = new A[2];
if(p<0)
{
delete [] Aptr;
throw p;
}
delete [] Aptr;
}
Put the array on the stack and let the normal stack unwinding handle it:
void abc(int p)
{
A Aptr[2];
if (p<0)
throw p;
}
Instead of using a raw pointer to point to the newly allocated array, hold onto it using a smart pointer class like scoped_array or shared_array, or some other RAII class:
void abc(int p)
{
boost::scoped_array<A> Aptr (new A[2]);
if(p<0)
throw p;
}
}
2 and 3 are really the only safe options in C++ code that uses exceptions - if you use raw pointers and manual memory management, you WILL end up with memory leaks sooner or later. No matter how careful you are, exception safe code pretty much requires RAII.
In addition to the suggestions concerning boost::shared_array and boost::scoped_array you could also just use std::vector:
std::vector<A> array( 2 );
if( p < 0 )
throw p;
Note that your types should be copyable if you go this route, however, as std::vector will copy them around during insert or when internally resizing, et cetera.
Could it be because you are not calling delete on your A class? If you don't delete a dynamically allocated class the desnstructor is not called.
because you allocated on the heap. What gets freed are the variables holding the pointer to the array of objects. Not the objects themselves.
Aptr is a heap-allocated variable, not a stack variable. You need to explicitly delete it for the destructor to be called (and to free the memory).
If you would instead do this:
A a[2];
and not
A *Aptr = new A[2];
you'd get the destructor called.
Anything you allocate dynamically you will have to deallocate yourself.
You created the object on the heap. The destructor will be callen when you delete the object.
If you don't create the object on the heap, the destructor will be called as you expected.