Return class pointer from a function - c++

I am not sure what is wrong with this (keep in mind I'm kinda sorta new to C++)
I have this class:
Foo
{
string name;
public:
SetName(string);
}
string Foo::SetName(string name)
{
this->name = name;
return this->name;
};
//////////////////////////////////////////////
//This is where I am trying to return a Foo pointer from this global function:
Foo * ReturnFooPointer()
{
Foo foo;
Foo * foo_ptr;
foo_ptr = &foo;
return foo_ptr;
}
At compile time, this compiles just fine. However at run time it throws a runtime exception(Some sort of access violation)
What am I doing wrong?

You need to use the new keyword instead to create new Foo on the heap.
The object on the stack will be freed when the function ends, so you are returning a pointer to an invalid place in memory.
Here is the correct code.
Foo * ReturnFooPointer()
{
Foo * foo_ptr = new Foo();
return foo_ptr;
}
Remember later to delete the pointer you are returning.
So later in code:
Foo *pFoo = ReturnFooPointer();
//Use pFoo
//...
delete pFoo;

You're returning a pointer to a local object on the stack. It goes out of scope the moment your function returns, and is invalid.
You should create a new instance to return, i.e.,
Foo* foo_ptr = new Foo();
This will create an object in the heap and will live until you call delete on it.

the actual object is allocated on the stack so it is destroyed when it goes out of scope (when the function returns). If you allocate it on the heap (with new), it will be alive until you delete it

Related

What will be happen if you dynamically allocates memory for one object of the class as an argument?

class Example
{
private:
Example* pointer;
Example* pointer2;
public:
Example();
void setPointer2(Example* object);
};
Example::Example()
{
pointer = new Example();
}
void Example::setPointer2(Example* object)
{
this->pointer2 = object;
}
int main()
{
Example object;
object.setPointer2(new Example());
return 0;
}
Delete is not important. I just want to know what is the differences between this two object which is adresses holding by pointer and pointer2. Are they differently allocated? The actual question is, does it matter where to use the "new" operator?
A major problem you have in your code is infinite recursion! The constructor you have defined:
Example::Example()
{
pointer = new Example();
}
creates a new object of its own type. This will call the constructor (again), and that call will call the constructor (again and again...)
But, other than that issue, it doesn't really matter whether you create a new object by directly assigning its address to pointer or if you create the object elsewhere and then assign its address (later) to pointer2. Both will point to an object of the class.

Does the destructor of an object allocated dynamically (on heap) will be called automatically in return function?

Maybe the question is basic but I didn't found answer for that.
I will give the some examples (when Object has destructor), and I will glad to understand what happens in each one:
1)
int f (){
Object *p=new Object();
int something=5;
return something;
}
I think it would not call the destructor, but someone told me that if the function has return then the destructor will be called.
2)
Object & f (){
Object *p=new Object();
return *p;
}
How about now? is it connected to the object instance we return?
if 1) is not calling detractor please confirm that 3) is not calling the destructor (I still think it will not, but confirming)
3)
int f (){
for(int i=0; i<10; i++){
Object *p=new Object();
}
int something=5;
return something;
}
If 1) is calling the destructor: if 3) was void function, does the destructor
will be called (I again think not).
In case #1, the destructor is NOT called, because the object exists in dynamic (heap) memory, so it will not be destructed until delete is called on it. Every new needs a matching delete.
The destructor WOULD be called if the object were created in automatic (stack) memory instead, eg:
int f() {
Object p; // <-- no 'new'
int something=5;
return something;
} // <-- ~Object() is called here
In case #2, the destructor of the object pointed to by p is NOT called, and the return statement is returning a reference to the same object that exists in dynamic memory.
If the function returned an Object by value instead of by reference, then the return statement would make a copy, and the copy WOULD be destructed (but not the original!) when the caller is done using the returned object, eg:
Object f() {
Object *p=new Object();
return *p; // <-- copy made here
}
f(); // <-- ~Object() for the return value
// is called when the ';' is reached
In case #3, again the objects being created in dynamic memory are NOT destructed automatically upon return.
In all three cases, you can use std::unique_ptr to provide automatic memory management of dynamic objects, eg:
int f() {
std::unique_ptr<Object> p(new Object);
int something=5;
return something;
} // <-- ~unique_ptr() is called here
std::unique_ptr<Object> f() {
std::unique_ptr<Object> p(new Object);
return std::move(p);
} // <-- ~unique_ptr() for p is called here
f(); // <-- ~unique_ptr() for the return value
// is called when the ';' is reached
int f() {
for(int i=0; i<10; i++) {
std::unique_ptr<Object> p(new Object);
} // <-- ~unique_ptr() is called here
int something=5;
return something;
}
Absolutely not. C++ is not garbage-collected like Java.
Every new has to be balanced with a delete, and you need to pass the pointer you get back from new to that call to delete. (More formally that pointer has to be the same type too, or polymorphically related).
Fortunately, C++ does provide smart pointer classes like std::unique_ptr that wrap the delete call in its destructor.

error: 'new' cannot appear in a constant-expression

class A
{
int data;
public:
void display()
{
cout<<"Value is "<<data;
}
void set_data(int x)
{
this->data = x;
}
A object = new A();
};
When I run the above code, I get the error stating "new cannot appear in constant expression". Why is it so?
Operator new returns a pointer but A is not a pointer type. You want A*:
A* object = new A();
You also want to move the above statement outside your class body and place it into appropriate function such as main():
int main() {
A* p = new A();
// do work
delete p;
}
That being said you either don't need a pointer at all and you can simply use an object with automatic storage duration:
A object;
Or you want to consider using a smart pointer such as std::unique_ptr:
std::unique_ptr<A> p = std::make_unique<A>();
class A
{
public:
A * object = new A(); // In any case not: "A object = new A();"
};
Or:
class A
{
public:
A object;
};
-
See (let's assume, for a moment, that you don't get the error), in both cases, on the first construction of A object, it creates another A object as a data-member. This A data-member (let's call it object.object ) creates in its turn another A as its data-member (let's call it object.object.object), and so to infinity (or until no more memory). I mean, as a data-member, it can't be either as A* object = new A();, or as A object;
-
I am not sure what was your intention, but if you want to link one A-object to another A-object, the class should be something like that:
class A
{
public:
A * object = nullptr
};
you have to make object of class A into main().
void main(){
A object;
}
First of all, you cannot create an object in the class declaration. Class declaration is like a blue print of the class. It is to say these are the components of my class - variables and member functions. You cannot instantiate anything inside it as no memory is allocated during this stage.
Note that you can instantiate an object inside one of the member function including constructor. These are called during object creation when memory is allocated.
Even if you use this statement inside a constructor you will go into an infinite loop as the constructor calls its constructor and so on until you have memory overflow.
You can declare the object in main like this:
int main() {
A obj = new A();
//other operations
} //Object A is destroyed once you come out of main.
Or dynamically like this
int main() {
A* obj = new A(); //dynamic allocation
//other operations
delete obj; //explicitly destroy
}

Deleting instantiated objects outside of a function?

How do you delete an instantiated object inside a function then delete when another function is called?
For example:
int function_test(){
object* a = new object();
}
int function_test2(){
delete a;
}
Object a needs to be deleted when function_test2() is called. Function_test() creates and sets the value of object a.
In order to delete something, you need a pointer to something.
When you allocate an object in function function_test and want to delete it in function_test2 you need to take care of a way for function_test2 to get a hold of the pointer to the object you wish to delete.
There are multiple ways of doing that, but the most common one is for function_test to return the pointer to the caller, and then passing that pointer to function_test2:
object* function_test() {
object* a = new object();
...
return a;
}
void function_test2(object* a) {
...
delete a;
}
The caller would need to "transfer" the pointer, like this:
object obj = function_test();
...
function_test2(obj);
Other ways of transferring the pointer are using file-static pointers, using global pointers, and using instance variables when functions function_test and function_test2 are member functions of a class.
You can't transfer local variables between functions. If you like to do something like this, I suggest you return the pointer, so you can pass it to the next function.
object *function_test()
{
auto *o = new object{};
return o;
}
however, this has as disadvantage that you have to capture this variable everywhere where you call it and have to to do memory management. Most likely you just want to use something object oriented, similar to:
class ObjectOwner final
{
public:
int function_test(){
a = new object();
}
int function_test2(){
delete a;
}
private:
object *a{nullptr};
};
which can be used as:
ObjectOwner owner;
owner.function_test();
owner.function_test2();
Even better would be using a std::unique_ptr<object> so that when you forget to call the 2nd function, the memory is freed.
Finally, you can consider using a constructor/destructor.
class ObjectOwner final
{
public:
ObjectOwner()
: a(std::make_unique<object>())
{
}
~ObjectOwner() = default;
void func() { /*Do something with a*/ }
private:
std::unique_ptr<object> a{};
};
Allowing you to write:
ObjectOwner owner{};
owner.func();

Destruct with a pointer to object

If an object exists as such:
MyClass obj;
To call a member function:
obj.myMemberFunction();
Then to call the destructor of that object after it fulfills its purpose:
delete obj;
However, lets say I have a pointer to an object:
MyClass* obj;
To call a member function:
obj->myMemberFunction();
Now... How do I call the destructor on this object?
You've got it backwards; do delete in the second case and not the first:
MyClass obj;
obj.myMemberFunction();
//delete obj;
//^^^^^^^^^^^
// NO! `obj` has automatic storage and will
// be destroyed automatically when it goes out
// of scope.
delete expects a pointer to a dynamically-allocated object:
MyClass* obj = new MyClass;
obj->myMemberFunction();
delete obj;
If you create it with
MyClass obj;
you do nothing to delete it. If you create it with
MyClass* obj = new MyClass();
you use
delete obj;
to delete it.
The operator delete is intended to be used with pointers that stores the adresses of areas allocated on the heap thanks to the corresponding operator new.
void function ()
{
int * pt;
pt = new int;
*pt = 42;
delete pt; // memory released
}
Memory allocated on the stack is automaticly released at the end of the corresponding scope :
void function ()
{
int i;
i = 42;
} // memory released
When you write MyClass obj;, the object is allocated on the stack, as opposed to on the heap. In this case, the object is destroyed automatically then it goes out of scope. The compiler generates code to ensure the destructor is called. So you don't delete the object explicitly.
delete is used when an object is allocated on the heap. For example:
MyClass* pobj = new MyClass;
// Do something with pobj...
delete pobj;