When to use "delete"? - c++

I want to store 10 Obj object in objList, but i don't know when is appropriate use delete in this case. If i use delete Obj; in the line where i note in below code, will the Obj still be stored in objList?
struct Obj {
int u;
int v;
};
vector<Obj> objList;
int main() {
for(int i = 0; i < 10; i++) {
Obj *obj = new Obj();
obj->u = i;
obj->v = i + 1;
objList.push_back(*obj);
// Should i use "delete Obj;" here?
}
}

Any object you create on the heap with new needs to be cleared up by delete. In your code, you are actually storing a copy in your collection.
objList.push_back(*Obj);
What this line is doing step by step is:
Indirecting a pointer to the underlying heap memory Obj occupies (returning the object Obj)
Calling the copy constructor to create a temporary copy
Storing the temporary copy in the collection
You do not need to create this initial Obj on the heap, a stack allocated local will suffice as #Luchian Grigore has pointed out.
Obj obj;
objList.push_back(obj);
You do not need to call delete on the copy in the collection, the STL collection will handle this memory itself when you remove the element, but you still will need to delete the original heap allocated object.
It would be better if you stored your objects by std::shared_ptr. That way delete would be called when all references to the Obj were removed.
std::vector< std::shared_ptr< Obj > > vec;
vec.push_back( std::make_shared( new Obj() ) );

Yes, you should.
There should be a corresponding delete for every new in your program.
But your program doesn't need dynamic allocation:
Obj obj;
obj.u = i;
obj.v = i + 1;
objList.push_back(obj);
Also, your syntax was wrong - objList.push_back(*Obj); // should be *obj, not *Obj

Think about what happens:
In your loop you create a new instance of Obj and assign some values to it. This instance is created on your heap - thus you have to free it afterwards. When you add the instance to the vector you implicitely create a copy of it - because you have a vector of objects, not of pointers. Thus the vector keeps its own copy of Obj. You are safe to delete your Obj instance.
BTW:
you could even reuse the object instance and create and free it outside of your loop
it's not necessary to allocate the Obj instance on the heap
Obj x; x.u =i; x.v = i+1; objList.push_back(x);
would also do
You should read some articles about smart pointers and smart pointer containers. Eg. boost::scoped_ptr, boost::shared_ptr, std::auto_ptr. Using these paradigms there's usually no need to call delete by yourself.

You wanna use the heap, so I suggest changing your vector declaration to vector of pointers, something like this.
vector<Obj *>objList;
Why? Because if it is a vector of Obj's, then the things you're storing are actually copies of the value Obj of the pointers you created. objList's items and the obj pointers you create are totally separated and unrelated!
So when you,
delete obj
The things on objList are totally completely unaffected in any ways.
Moreover, vector<Obj> (no asterisk), stores its item as Obj and they are on the stack, they will disappear when your program goes out of scope!

Well, the simple rule is that each variable constructed by new should be clean up by delete.
However depending on your goal, you may not need write the delete yourself.
At home, when learning the gory details of memory management, you will probably write as many delete as you write new.
Professionals, however, never use delete in applicative code (*). delete is a code smell. It's the shortest way to memory leaks in the presence of exceptions. Professionals use RAII to deal with exceptions safely, and namely: smart pointers/smart containers.
(*) as opposed to library code, ie someone wrote that shared_ptr class one day.

Related

Memory deallocation inside a member function

I was thinking about a this situation not for a real implementation but to understand better how pointers works.
class foo(){
foo();
~foo();
void doComplexThings(const std::vector<int*>& v){
int* copy;
for(int i = 0; i < v.size(); i++){
copy = v[i];
// do some stuffs
}
}
}
main(){
std::vector<int*> myVector; // suppose we have 100 elements
doComplexThings(myVector);
for(int i = 0; i < myVector.size(); i++){
delete myVector[i];
}
myVector.clear();
}
Ok, I know that have no sense to copy v[i] inside an other pointer, but I was thinking: copy do a memory leak?
After the execution of doComplexThings(), copy will continue to exist and will occupy space in the heap?
After deleting all elements it will continue to exist and point to a deallocated memory?
So logically if I do this things with complex objects I'll keep occupy the memory with unreference object? Or copy is saved in the stack because I don't use new? And at the end of doComplexThings it will be deleted?
I'm a bit confused, thanks!
There is some confusion on the topic of pointers in the C++ community. While it is true that smart pointers have been added to the library to alleviate problems with dynamic memory allocation, raw pointers are not obsolete. In fact, whenever you want to inspect another object without owning it, you should use a reference or raw pointer, depending on which suits your needs. If the concept of ownership is unclear to you, think of an object as being owned by another object if the latter is responsible for cleaning up afterwards (deleting the former).
For example most uses of new and delete should be replaces with the following (omitting std for brevity):
{
auto ptr_to_T = make_unique<T>(//constructor params);
do_stuff_with_smart_ptr(ptr_to_T);
do_stuff_with_T(*ptr_to_T);
do_stuff_with_raw_ptr(ptr_to_T.get());
} // automatic release of memory allocated with make_unique()
Notice how a function that takes a T* doesn't need a smart pointer if it doesn't keep a copy of the T* it is given, because it doesn't affect the lifetime of the object. The object is guaranteed to be alive past the return point of do_stuff_with_T() and its function signature signals that it doesn't own the object by taking a raw pointer.
On the other hand, if you need to pass the pointer to an object that is allowed to keep the pointer and reference it later, it is unclear when the object will need to be destroyed and most importantly by whom. This is solved via a shared pointer.
ClassThatNeedsSharedOwnership shared_owner;
{
auto ptr_to_T = make_shared<T>(//constructor params);
shared_owner.set_T(ptr_to_T);
// do a lot of stuff
}
// At this point ptr_to_T is destroyed, but shared_owner might keep the object alive
So how does the above factor in to your code. First of all, if the vector is supposed to own (keep alive) the ints it points to, it needs to hold unique_ptr<int> or shared_ptr<int>. If it is just pointing to ints held by something else, and they are guaranteed to be alive until after the vector is destroyed, you are fine with int*. In this case, it should be evident that a delete is never necessary, because by definition your vector and the function working on the vector are not responsible for cleaning-up!
Finally, you can make your code more readable by changing the loop to this (C++11 which you've tagged in the post):
for (auto copy : v){
// equivalent to your i-indexed loop with copy = v[i];
// as long as you don't need the value of i
do_stuff_to_int_ptr(copy);
// no delete, we don't own the pointee
}
Again this is only true if some other object holds the ints and releases them, or they are on the stack but guaranteed to be alive for the whole lifetime of vector<int*> that points to them.
No additional memory is allocated on the heap when you do this:
copy = v[i];
variable copy points to the same address as v[i], but no additional array is allocated, so there would be no memory leak.
A better way of dealing with the situation is to avoid raw pointers in favor of C++ smart pointers or containers:
std::vector<std::vector<int>> myVector;
Now you can remove the deletion loop, which is an incorrect way of doing it for arrays allocated with new int[length] - it should use delete[] instead:
delete[] myVector[i];
Basically you're illustrating the problem with C pointers which lead to the introduction of C++ unique and shared pointers. If you pass a vector of allocated pointers to an opaque member function, you've no way of knowing whether that function hangs onto them or not, so you don't know whether to delete the pointer. In fact in your example you don't seem to, "copy" goes out of scope.
The real answer is that you should only seldom use allocated pointers in C++ at all. The stl vector will serve as a safer, easier to use version of malloc / new. Then you should pass them about as const & to prevent functions from changing them. If you do need an allocated pointer, make one unique_ptr() and then you know that the unique_ptr() is the "owner" of the memory.

Delete created Objects inside List

I'm creating some Objects inside a loop and add it to a listwith:
list<MyObject> myList;
MyObject* ob = new MyObject();
ob.setAttribute("whatever");
myList.push_back(*ob);
After the loop finishes, I'm using the list several times.
I've started now a Leak Detector and saw, that I've to delete all the MyObject objects.
How I delete them properly (In the destructor?). Should I use a iterator? But how I get the real object - and not the iterator pointer?
Thanks a lot.
There's absolutely no reason for dynamic allocation here, since the list stores objects by value. All you're doing is copying and discarding a dynamic object; it's leaked immediately since you don't keep a pointer to it anywhere. Just push objects directly, copying a temporary or automatic variable if necessary:
list<MyObject> myList;
MyObject ob;
ob.setAttribute("whatever");
myList.push_back(ob);
If you did need to store pointers, perhaps for polymorphism, then you'd use smart pointers to avoid leaks:
list<std::unique_ptr<MyBase>> myList;
std::unique_ptr<MyObject> ob(new MyObject);
ob->setAttribute("whatever");
myList.push_back(ob);
If you really want to juggle raw pointers for some reason, then yes, you will have to delete them yourself. You really shouldn't try to do that.
You don't need to delete them, they're copied when added into the list by push_back(). But, you need to delete ob after you used it. Such as:
list<MyObject> myList;
MyObject* ob = new MyObject();
ob.setAttribute("whatever");
myList.push_back(*ob);
delete ob;
Basically, you don't need to use pointer here, you can just declare ob in stack to avoiding the manual memory management:
list<MyObject> myList;
MyObject ob;
ob.setAttribute("whatever");
myList.push_back(ob);
And, according to your program's requirment, you can use some kind of smart point to avoiding such manual memory management, such as:
list<std::shared_ptr<MyObject>> myList;
myList.push_back(new MyObject);
...
// don't need to delete them manually

destructing an object stored in the vector of pointers [duplicate]

This question already has answers here:
Does std::list::remove method call destructor of each removed element?
(6 answers)
Closed 9 years ago.
I have a class that contains pointers, the class inherits nothing
class MyClass
{
public:
MyClass();
~MyClass();
private:
//i have pointers here
};
MyClass::~MyClass()
{
print("destroyed..");
}
Now i have to use this class as a pointer in vector like this:
vector<MyClass*> classes;
Push some classes in here but when i remove an element:
classes.remove(index);
The destructor doesn't get called,and i think that I have a memory leak.
So how do i make it call the destructor
A vector of pointers does nothing to delete the pointers when they get removed or cleared from it. The vector cannot know if the pointers are dynamically allocated or not. It is not it's job to call delete.
It is up to you to call delete on the pointers, if and when it is necessary. There are not enough details in your question to determine whether it is necessary at all (you haven't shown how the objects pointed to are allocated). But since you claim there is a memory leak, this could indicate that they are dynamically allocated. The immediate solution is to call delete:
delete *it;
classes.erase(it); // vector has no remove member function
A safer solution is to store unique ownership smart pointers, such as std::unique_ptr<MyClass>. The standard library also provides smart pointers for shared and weak ownership. See Smart Pointers.
All the above is assuming that you do actually need to store a pointer. In general, it is safer and clearer to store values:
std::vector<MyClass> classes; // but don't call it "classes". A vector stores objects.
That's one of the reasons why you should avoid using std::vector<MyClass*> at first place. There's an ugly memory management connected with it and it won't stay as easy as classes.remove(index);
Basically, for every new a delete must be called and for every new[] a delete[] must be called, no matter whether you use this pointer as a local variable or you put it into the vector:
vector<MyClass*> vec;
vec.push_back(new MyClass()); // <-- object has been created
...
delete classes[index]; // <-- object shall be destructed
// the delete call will automatically invoke the destructor if needed
...
// now you can remove the dangling pointer from the vector
Just note that once the object has been destructed, any (old) reference to this object is invalid and trying to access this object using such reference (dangling pointer) will yield undefined behavior.
Firstly, std::vector has no remove, you probably mean erase.
Secondly, you need to manually call delete on whatever you're removing:
vector<MyClass*> classes;
auto iter = <iterator to index to remove>;
delete *iter;;
classes.erase(iter);
Or, to avoid all this pain, use a std::unique_ptr<MyClass>.
It is unclear who is responsible for managing the lifetime of the objects pointed by the pointers inside classes. Have you pushed newed pointers into it, or have you pushed the addresses of automatic storage objects?
If you have done the former, then you must manually delete the pointer before removing it. Else, if you have done the latter, then you could just leave it as is, just leaving the pointed-to objects destroy themselves as they leave their respective scopes. If you have mixed newed and non-newed pointers, whose possibility isn't that remote as you would think, then you're definitely damned, undefined behavior making demons fly out of your nose.
These kinds of situations involving pointers are very ambiguous, and it is generally recommended not to use pointers at all, and make the std::vector store plain objects, which makes your object lifetime management much simpler and the making the declaration just speak for itself.
vector<MyClass> classes; // Do this instead
You have to manually delete your pointers before your application exit or after your class object is removed from vector.
// Delete all
vector<MyClass*>::iterator it = classes.begin();
while (it != classes.end()) {
delete *it;
it = classes.erase(it);
}
Tip: Never add stack constructed pointers like following:
MyClass m;
classes.push_back(&m);
Edit: As suggested by other member the better solution is:
MyClass m(/* ... */);
vector<MyClass> classes;
classes.push_back(m);
However please note, you have to properly implement the copy constructor especially if your class has pointer data members that were created with new.
Make a temp pointer to hole MyClass* pointer before you remove it from your vector.
vector<MyClass*> classes;
//push some classes in here but
//when i remove an element
MyClass* temp = classes[index];
classes.remove(index);
// call delete temp; if you want to call the destructor thus avoid memory leak.
delete temp;
To avoid memory leak, remember never to loose control of heap object, always keep a a pointer or reference to it before object release.
It seems that you want your vector to be manager of your items.
Take a look at boost::ptr_vector class
its basically a wrapper around std::vector class.
You declare that this vector is the "holder" of these pointers, and if you remove them from this containers you want them to be deleted.
#include <boost/ptr_container/ptr_vector.hpp>
...
boost::ptr_vector<MyClass> myClassContainer;
myClassContainer.push_back(new MyClass());
myClassContainer.clear(); // will call delete on every stored object!

STL Containers & Memory Management - list of objects vs. list of pointers to objects

I have had a good look at some other questions on this topic and none of them (to my knowledge) address how to correctly erase items from a stl list of objects which contain dynamicically assigned memory vs. a stl list of objects that don't contain dynamically assigned memory.
I want to use a list of objects. Take this object for example (which contains no dynamically assigned memory):
class MyPoint {
public:
MyPoint(int _x,int _y)
{
x = _x;
y = _y;
}
private:
int x;
int y;
};
So I might create a list of objects (not pointers to them), add things to it and then erase an element:
list<MyPoint> myList;
myList.push_back(MyPoint(3,4));
myList.push_back(MyPoint(1,2));
myList.push_back(MyPoint(8,8));
myList.push_back(MyPoint(-1,2));
list<MyPoint>::iterator it;
it = myList.begin();
advance(it,2);
myList.erase(it);
My list now contains:
(3, 4)
(1, 2)
(-1, 2)
QUESTION 1a: do I need to do anything else to the erased object or will the memory be taken care of?
QUESTION 1b: if the program ends, do I need to do something with the remaining objects in the list? Do I need to delete them all and deal with their memory somehow?
Ok, now consider an alternative version of the class that allowed a point in N-dimensional space. I.e., I could dynamically assign an array of length N to hold the N points inside the class (I have spared you the implementation as that is not in question here). The destructor of the class would then delete the dynamically assigned array using 'delete'.
class MyDynamicPoint {
public:
MyDynamicPoint(int N)
{
points = new int[N];
}
~MyDynamicPoint()
{
delete points;
points = NULL;
}
private:
int *points;
};
I might now create a list of pointers to the objects, instead of the objects themselves:
list<MyDynamicPoint*> myList;
myList.push_back(new MyDynamicPoint(8));
myList.push_back(new MyDynamicPoint(10));
myList.push_back(new MyDynamicPoint(2));
myList.push_back(new MyDynamicPoint(50));
list<MyDynamicPoint*>::iterator it;
it = myList.begin();
advance(it,2);
myList.erase(it);
QUESTION 2a - Is the above correct? I.e. Because this new version of the class would contain some dynamically assigned memory, does this mean I have to create a list of pointers to objects, not the objects themselves?
QUESTION 2b - Given that I have just erased the pointer from the list, where do I call delete to deal with the fact there is now dynamic memory to be deleted in the objects? Or does the erase method of stl list call the destructor of the object, taking care of it?
Many thanks in advance for any help,
Best,
Adam
When you have a class with data members that have automatic storage duration (i.e. their lifetime is tied to the instance of this class) like this:
class MyPoint {
private:
int x;
int y;
};
and you will use list<MyPoint> myList;, then this instance of std::list is also an object with automatic storage duration, that will be cleaned up automatically and by the time the container is destructed, so are the elements it holds. Everything is taken care of.
But the latter version is not very lucky choice... not only that you have a container holding pointers, you even decided to create a data member of class Point that will be allocated dynamically. At first note that everything that has been allocated by calling new should be freed by calling delete and everything allocating by calling new[] should be freed by calling delete[].
In this situation, you are allocating the memory when the object is constructed and cleaning it up when the object is destructed:
MyDynamicPoint(int N)
{
points = new int[N];
}
~MyDynamicPoint()
{
delete[] points;
points = NULL;
}
private:
int *points;
You would achieve the same by using some std::vector or std::array instead of the C-style array and you wouldn't have to take care of the memory management on your own:
MyDynamicPoint(int N) : points(std::vector<int>(N, 0)) { }
private:
std::vector<int> points;
the std::vector object will take care of memory management for you.
And last thing: when you dynamically allocate an element and store it into the container:
myList.push_back(new MyDynamicPoint(8));
you need to free this memory on your own, erasing the pointer from the list is not enough:
list<MyDynamicPoint*>::iterator it;
...
delete *it;
myList.erase(it);
So whatever you want to achieve, always prefer objects with automatic storage duration if the situation allows it. There's nothing worse than being forced to taking care of memory management manually and dealing with unpleasant problems such as memory leaks later.
QUESTION 1a: do I need to do anything else to the erased object or will the memory be taken care of?
You don't need to do anything.
QUESTION 1b: if the program ends, do I need to do something with the remaining objects in the list? Do I need to delete them all and deal with their memory somehow?
You don't need to do anything.
QUESTION 2a - Is the above correct?
The code is not correct. You're violating The Rule of Three. In particular, the automatically-generated MyDynamicPoint's copy constructor and assignment operator will make a bitwise copy of the points pointer. If you copy an instance of MyDynamicPoint, you'll end up with two object sharing the same points pointer:
When one of the objects goes of scope, the other becomes unusable.
When the second object goes out of scope, its destructor will attempt to free memory that's already been freed. This is undefined behaviour.
I.e. Because this new version of the class would contain some dynamically assigned memory, does this mean I have to create a list of pointers to objects, not the objects themselves?
No, it does not mean that. In fact, you should probably continue to store objects by value. However, you do need to fix the rule of three.
QUESTION 2b - Given that I have just erased the pointer from the list, where do I call delete to deal with the fact there is now dynamic memory to be deleted in the objects? Or does the erase method of stl list call the destructor of the object, taking care of it?
Since you have a list of raw pointers, the destructors will not be called automatically. The easiest way to fix that is to either store objects by value, or use std::unique_ptr or std::shared_ptr instead of raw pointers.
To question 1, there is nothing you need to do. As you store the objects by value the compiler and the library will handle everything.
However, when you store pointer as in the second case, you need to delete those pointers that you have allocated with new, or you will have a memory leak.
And you have to delete the pointers before doing the erasing, as that can invalidate the iterator:
delete *it;
myList.erase(it);
I think following should work
MyPoint* ptr = myList.back();
delete ptr;
myList.pop_back();
OR
MyPoint* ptr = myList.back();
delete ptr;
myList.erase(ptr);

How to Convert beween Stack and Heap Objects

Example:
Class *_obj1;
Class *_obj2;
void doThis(Class *obj) {}
void create() {
Class *obj1 = new Class();
Class obj2;
doThis(obj1);
doThis(&obj2);
_obj1 = obj1;
_obj2 = &obj2;
}
int main (int argc, const char * argv[]) {
create();
_obj1->doSomething();
_obj2->doSomething();
return 0;
}
This creates 2 objects, creates pointers to them, then main() calls a method on each. The Class object creates a char* and stores the C string "Hello!" in it; the ~Class() deallocator frees the memory. The doSomething() method prints out "buff: %s" using printf(). Simple enough. Now if we run it we get this:
Dealloc
Buff: Hello!
Buff: ¯ø_ˇ
Obviously the stack object does not work here - it's obvious that when the function exits the pointer _obj2 is pointing at a location in the stack. This is why I used heap objects in my previous question, which people told me was "stupid".
So, the first question is: if how can I convert the stack object (obj2) to a heap object so it's not deallocated after create() exits? I want a straight answer, not an arrogant "you're doing it wrong" as so many have done. Because in this case stack objects cannot work so heap objects seem to be the only way. EDIT: Also, converting back to a stack object would be useful as well.
The second question: the specific example of heap objects being "wrong" was creating a new vector<string>* using the new operator. If dynamically allocating STL objects is wrong, then what's the right way? Obviously if you create them as stack objects it fails because they're immediately deallocated, but I've been told (again, by a very high-ranking member) that dynamically allocating them can corrupt the heap. So what's the right way to do it?
So, the first question is: if how can I convert the stack object (obj2) to a heap object so it's not deallocated after create() exits? I want a straight answer,
The straight answer is: You can't "convert" an object between the stack and heap. You can create a copy of the object that lives in the other space, as others have pointed out, but that's it.
The second question: the specific example of heap objects being "wrong" was creating a new vector* using the new operator. If dynamically allocating STL objects is wrong, then what's the right way? Obviously if you create them as stack objects it fails because they're immediately deallocated, but I've been told (again, by a very high-ranking member) that dynamically allocating them can corrupt the heap.
Dynamically allocating STL objects will not on its own corrupt the heap. (No idea where you might have heard that.)
If you want to use a stack-allocated STL object outside of the function that you created it in, you can't, since the stack space in which the object resides is only valid inside the function that created it.
You can, however, return a copy of the object:
std::vector<char> SomeFunc()
{
std::vector<char> myvector;
// myvector.operations ...
return myvector;
}
As I said, though, this will return a copy of the object, not the original object itself -- that would be impossible, since the stack that contains the object is unwound after the function returns.
One other option is to have the caller pass in a reference / pointer to the object that your function manipulates, if this makes sense for your particular scenario:
void SomeFunc(std::vector<char>& destination)
{
// destination.operations ...
}
void AnotherFunc()
{
std::vector<char> myvector;
SomeFunc(myvector);
}
As you can see, you've still allocated everything on the stack, and you avoid the (sometimes consequential) overhead of relying on the copy-constructor to return a copy of the object.
So, the first question is: if how can I convert the stack object (obj2) to a heap object so it's not deallocated after create() exits?
This line:
_obj2 = &obj2;
Change to:
_obj2 = new Class(obj2); // Create an object on the heap invoking the copy constructor.
I want a straight answer, not an arrogant "you're doing it wrong" as so many have done.
Thats as straight an answer as you can get. Obviously you are new to C++, So I am sure this will nto work as intended because you have probably made a couple of mistakes in the defintion of the class "Class" (by the way terrible name).
Also, converting back to a stack object would be useful as well.
class obj3(*_obj2); // dereference the heap object pass it to the copy constructor.
The second question: the specific example of heap objects being "wrong" was creating a new vector<string>* using the new operator. If dynamically allocating STL objects is wrong, then what's the right way?
Why do you dynamically allocate the vector. Just create it locally.
std::vector<std::string> funct()
{
std::vector<std::string> vecString;
// fill your vector here.
return vecString; // Notice no dynamic allocation with new,
}
Using new/delete is using C++ like C. What you need to read up on is smart pointers. These are obejcts that control the lifespan of the object and automatically delete the object when they go out of scope.
std::auto_ptr<Class> x(new Class);
Here x is a smart pointer (of type auto_ptr) when it goes out of scope the object will be deleted. But you can return an auto_ptr to the calling function and it will be safely transfered out of the function. Its actually a lot more complicated than that and you need a book.
Obviously if you create them as stack objects it fails because they're immediately deallocated,
Its de'allocated when it goes out of scope.
but I've been told (again, by a very high-ranking member) that dynamically allocating them can corrupt the heap.
If you do it incorrectly. Which given your knowledge is very likely. But hard to verify since you have not provided the definition of Class.
So what's the right way to do it?
Learn why you should use stack objects
Learn what smart pointers are.
Learn how to use smart pointers to control lifespans of objects.
Learn the different types of smart pointers.
Look up what the separation of concerns is (you are not following this basic principle).
You have to either copy-construct a new heap object (Class * foo = new Class(obj2)) or assign the stack object to a heap object (*obj1 = obj2).
the only way is to copy object.
Change declaration to:
Class _obj2;
and assign:
_obj2 = obj2;
Taking the address of a stack variable won't magically transfer it into heap. You need to write a proper copy-constructor for your class and use _obj2 = new Class(obj2);.
As for STL containers, they allocate their data on the heap anyway, why would you want to allocate container itself on the heap? Put them in a scope that will keep them alive as long as you need them.
Your stack object is created inside the create function and is deallocated as soon you get out of scope of the function. The pointer is invalid.
You could change Class* obj2 to Class obj2 and the assign (which means copy) the object by obj2 = obj2;
I think you're really trying to ask "How can I return an object created inside my function?" There are several valid ways:
Allocate on the heap and return a pointer
Use an automatic variable and return its value, not a pointer (the compiler will copy it)
Let the caller provide storage, either by pointer or reference parameter, and build your object there.