What does "new (&variable) value;" in C++ do? - c++

Say I have the following code in a C++ program:
Object a = Object(someParameters);
new (&a) Object(someOtherParameters);
My assumption is that it replaces the contents of a with Object(someOtherParameters), avoiding a possible operator= declared for Object. Is this correct?

It's called placement new. It calles the constructor on the specified memory rather than allocating new memory. Note that in this case you have to explicitly call the destructor of your object before freeing the allocated memory.
Clarification. Suppose you have allocated some raw memory
char * rawMemory = new char [sizeof (Object)];
and you want to construct an object on that memory. You call
new(rawMemory) Object(params);
Now, before freeing the memory
delete [] rawMemory;
you will have to call the derstuctor of Object explicitly
reinterpret_cast<Object*>(rawMemory)->~Object();
In your particular example, however, the potential problem is that you haven't properly destroyed the existing object before constructing a new one in its memory.
Bonus:
Ever wondered how standard std::vector can do without its contained objects being default-constructible? The reason is that on most, if not all, implementations allocator<T> does not store a T* p which would require T to be default-constructible in case of p = new T[N]. Instead it stores a char pointer - raw memory, and allocates p = new char[N*sizeof(T)]. When you push_back an object, it just calls the copy constructor with placement new on the appropriate address in that char array.

It's known as placement new: it constructs the new Object at the address given inside the parentheses. Placement new is usually used to create an object in raw memory. Constructing a new object on top of an existing one, as this code does, is a bad idea, because it doesn't call the destructor on the original object.

Related

How to manually initialize std::list 's objects in C++? What to do if a pointer of class has a member list<>, can not use new?

Suppose this is a struct/class in c++
struct MyClass{
list<int> ls;
};
Now maybe due to some reason, it is not possible to initialize pointer of 'MyClass', and the memory is being allocated manually
MyClass *pointer = calloc(1, sizeof(MyClass));
pointer->ls.push_back(123); // <----- this line causes core dump
Although it works fine with pure C++ method like this:-
MyClass *pointer = new MyClass;
pointer->ls.push_back(123);// All good, no problem
So is there any function available in std::list to resolve this issue?
I tried doing the same with std::vector, by there was no problem in that when I used calloc()
struct MyClass{
vector<int> ls;
};
MyClass *pointer = calloc(1, sizeof(MyClass));//using calloc
pointer->ls.push_back(123); // All Good
But on doing this using malloc:-
struct MyClass{
vector<int> ls;
};
MyClass *pointer = malloc(1, sizeof(MyClass));//using malloc
pointer->ls.push_back(123); // Core dump :-(
C++ differentiates between memory and objects in that memory. You are allocating memory with malloc or calloc, but you are not creating any object in the memory you allocated.
You can manually create an object in allocated storage using the placement-new expression:
new(pointer) MyClass /*initializer*/;
This creates a new MyClass object at the storage location that pointer points to. /*initializer*/ is the optional initializer for the object and has the same meaning as in a variable declaration
MyClass my_class /*initializer*/;
You may need to #include<new> to use the placement-new form I used above and you need to make sure that the allocated memory block is large enough and sufficiently aligned for the MyClass object type.
Using a pointer as if it points to an object even though none was created at the storage location causes undefined behavior, which you are observing. Note that this is true for any (even fundamental) types technically. Probably that will change in the future to allow at least trivial types (or some similar category) to be created implicitly when used, but for non-trivial class types such as the standard containers, this certainly will not change.
Also note that malloc and calloc return void*, which in C++ cannot be implicitly cast to a different pointer type. You need to cast it explicitly:
MyClass *pointer = static_cast<MyClass*>(malloc(sizeof(MyClass)));
or rather than doing that, save the pointer as void* without any cast to hint at you that it is not actually pointing to an object, but just memory.
You can still pass that void* pointer to the placement-new and the placement-new will actually return you a pointer of the correct type pointing to the new object (there are some specific cases where you are actually required to use this pointer):
void *mem_ptr = malloc(sizeof(MyClass));
auto obj_ptr = new(mem_ptr) MyClass /*initializer*/;
You should also avoid using malloc and calloc and the like. C++ has its own memory allocation function, called (confusingly) operator new. It is used like malloc (initializing the memory to zero like calloc does is not useful, because the initializer in the placement-new can and/or will do that):
void* pointer = operator new(sizeof(MyClass));
and its free analogue is:
operator delete(pointer);
It still only allocates memory and does not create object as the placement new does.
The non-placement new expression new MyClass; allocates memory (by call to operator new) and creates an object as if by the placement-new form mentioned above.
You do not need to bother with all of this though, because you can just use a smart pointer and initialize it later, if you need that:
std::unique_ptr<MyClass> ptr; // No memory allocated or object created
ptr = std::make_unique<MyClass>(/*constructor arguments*/); // Allocates memory and creates object
// Object is automatically destroyed and memory freed once no `std::unique_ptr` references the object anymore.
You should not use raw pointers returned from new, malloc or the like as owning pointers in the first place. std::unique_ptr has the correct ownership semantics by default and requires no further actions by you.

Custom allocator including placement new case

I'm trying to implement a custom allocator for C++ that works on any form of new/delete/malloc/free. How my program works, I allocate at the start of the program a memory pool of x bytes and work with them. For example, when someone writes int* a= new int; my program will return the address from the memory pool which is available and marks it as allocated and that address along with the size allocated is removed from the memory pool. When someone writes delete a; the address is returned to the memory pool and can be used again. My problem is that I don't fully understand how new(placement) works and how should I deal with it, because when my function gets called to allocate memory on new/malloc I have as a parameter only the size of the memory the program needs and I just return an available address to that memory to be used. Consider the following example
auto p = (std::string*)malloc(5 * sizeof(std::string));
void * placement = p;
new(placement) std::string(4, (char)('a'));
std::cout<< *p;
On the first line my custom allocated will return to p an address from my memory pool where there is memory available of a total of 5* sizeof(std::string)), on the third line my custom allocator will allocate again memory returning another address. When I print *p it prints exactly what I was expected aaaa.
Is this how it should work?
A normal new does two things:
allocate storage; and
construct an object.
Now we want to separate these two steps. Allocating raw storage is easy, but there is no "native" way to construct an object at a given address in C++. Therefore, the new operator is overloaded to serve this purpose, by returning the given pointer for the first step.
We don't need a corresponding delete, because we can call the destructor manually. In C++17, std::destroy_at was added to the standard library. Since C++20, std::construct_at can be used to construct an object instead of placement new:
std::construct_at(p, 4, 'a');
The C++ Super-FAQ explains placement new very well:
What is “placement new” and why would I use it?
There are many uses of placement new. The simplest use is to place an
object at a particular location in memory. This is done by supplying
the place as a pointer parameter to the new part of a new expression:
#include <new> // Must #include this to use "placement new"
#include "Fred.h" // Declaration of class Fred
void someCode()
{
char memory[sizeof(Fred)]; // Line #1
void* place = memory; // Line #2
Fred* f = new(place) Fred(); // Line #3 (see "DANGER" below)
// The pointers f and place will be equal
// ...
}
Line #1 creates an array of sizeof(Fred) bytes of memory, which is
big enough to hold a Fred object. Line #2 creates a pointer place
that points to the first byte of this memory (experienced C
programmers will note that this step was unnecessary; it’s there only
to make the code more obvious). Line #3 essentially just calls the
constructor Fred::Fred(). The this pointer in the Fred
constructor will be equal to place. The returned pointer f will
therefore be equal to place.
ADVICE: Don’t use this “placement new” syntax unless you have to. Use it only when you really care that an object is placed at a
particular location in memory. For example, when your hardware has a
memory-mapped I/O timer device, and you want to place a Clock object
at that memory location.
DANGER: You are taking sole responsibility that the pointer you pass to the “placement new” operator points to a region of memory that is
big enough and is properly aligned for the object type that you’re
creating. Neither the compiler nor the run-time system make any
attempt to check whether you did this right. If your Fred class
needs to be aligned on a 4 byte boundary but you supplied a location
that isn’t properly aligned, you can have a serious disaster on your
hands (if you don’t know what “alignment” means, please don’t use
the placement new syntax). You have been warned.
You are also solely responsible for destructing the placed object.
This is done by explicitly calling the destructor:
void someCode()
{
char memory[sizeof(Fred)];
void* p = memory;
Fred* f = new(p) Fred();
// ...
f->~Fred(); // Explicitly call the destructor for the placed object
}
This is about the only time you ever explicitly call a destructor.

Understanding c++ new operator

Assume that ITEM is a class
ITEM* items = new ITEM[10];
for(i=0;i<10;++i)
new(&items[i)ITEM();
new(&items[0])ITEM(items[1]);
Is the above valid?
The way I understand it is that the last 2 uses of the new operator
do not allocate memory. They just invoke the constructor of ITEM.
Is the above equivalent to?
ITEM* items = new ITEM[10];
for(i=0;i<10;++i)
items[i] = ITEM();
item[0] = ITEM(items[1]);
EDIT:
https://github.com/gosom/practice-cpp/blob/master/arrays/darray.h
I use it here (for practicing)
The way I understand it is that the last 2 uses of the new operator do not allocate memory. They just invoke the constructor of ITEM.
Yes. This is the "placement new" operator, wich does not allocate memory and calls object constructor. This is legal to proceed the way you do, though ITEM constructor will be called twice (meaning that the ITEM class constructor will be executed twice: one when standard new is called, one when placement new is called). This may lead to memory leak (or other unexpected behavior) if some ressources are allocated in ITEM's constructor. See this for more info about placement new.
Is the above equivalent to?
No, this is not equivalent. In the latter case, you create a temporary object at each loop, which you copy to item[i]. This will call ITEM constructor, assignment operator, and destructor, at each loop. In the previous situation, placement new only calls ITEM constructor, nothing else.
The typical usage of "placement new" is when you want your object to be allocated in a specific memory area (instead of the heap, where standard new operator allocates memory). This may be shared memory or so... "Placement new" is one of the few situations where the object destructor can/must be called explicitely, i.e.: item[i]->~ITEM()
for(i=0;i<10;++i)
new(&items[i)ITEM();
The above is potentially invalid. The new operator constructs each object in the array already. This is double construction (which can and probably will lead to errors for less than trivial types).
for(i=0;i<10;++i)
items[i] = ITEM();
This just assigns a default constructed object to each entry in the array. This is as safe as the assignment operator is.
In general placement new is supposed to be used on raw memory.

When is a C++ destructor called?

Basic Question: when does a program call a class' destructor method in C++? I have been told that it is called whenever an object goes out of scope or is subjected to a delete
More specific questions:
1) If the object is created via a pointer and that pointer is later deleted or given a new address to point to, does the object that it was pointing to call its destructor (assuming nothing else is pointing to it)?
2) Following up on question 1, what defines when an object goes out of scope (not regarding to when an object leaves a given {block}). So, in other words, when is a destructor called on an object in a linked list?
3) Would you ever want to call a destructor manually?
1) If the object is created via a pointer and that pointer is later deleted or given a new address to point to, does the object that it was pointing to call its destructor (assuming nothing else is pointing to it)?
It depends on the type of pointers. For example, smart pointers often delete their objects when they are deleted. Ordinary pointers do not. The same is true when a pointer is made to point to a different object. Some smart pointers will destroy the old object, or will destroy it if it has no more references. Ordinary pointers have no such smarts. They just hold an address and allow you to perform operations on the objects they point to by specifically doing so.
2) Following up on question 1, what defines when an object goes out of scope (not regarding to when an object leaves a given {block}). So, in other words, when is a destructor called on an object in a linked list?
That's up to the implementation of the linked list. Typical collections destroy all their contained objects when they are destroyed.
So, a linked list of pointers would typically destroy the pointers but not the objects they point to. (Which may be correct. They may be references by other pointers.) A linked list specifically designed to contain pointers, however, might delete the objects on its own destruction.
A linked list of smart pointers could automatically delete the objects when the pointers are deleted, or do so if they had no more references. It's all up to you to pick the pieces that do what you want.
3) Would you ever want to call a destructor manually?
Sure. One example would be if you want to replace an object with another object of the same type but don't want to free memory just to allocate it again. You can destroy the old object in place and construct a new one in place. (However, generally this is a bad idea.)
// pointer is destroyed because it goes out of scope,
// but not the object it pointed to. memory leak
if (1) {
Foo *myfoo = new Foo("foo");
}
// pointer is destroyed because it goes out of scope,
// object it points to is deleted. no memory leak
if(1) {
Foo *myfoo = new Foo("foo");
delete myfoo;
}
// no memory leak, object goes out of scope
if(1) {
Foo myfoo("foo");
}
Others have already addressed the other issues, so I'll just look at one point: do you ever want to manually delete an object.
The answer is yes. #DavidSchwartz gave one example, but it's a fairly unusual one. I'll give an example that's under the hood of what a lot of C++ programmers use all the time: std::vector (and std::deque, though it's not used quite as much).
As most people know, std::vector will allocate a larger block of memory when/if you add more items than its current allocation can hold. When it does this, however, it has a block of memory that's capable of holding more objects than are currently in the vector.
To manage that, what vector does under the covers is allocate raw memory via the Allocator object (which, unless you specify otherwise, means it uses ::operator new). Then, when you use (for example) push_back to add an item to the vector, internally the vector uses a placement new to create an item in the (previously) unused part of its memory space.
Now, what happens when/if you erase an item from the vector? It can't just use delete -- that would release its entire block of memory; it needs to destroy one object in that memory without destroying any others, or releasing any of the block of memory it controls (for example, if you erase 5 items from a vector, then immediately push_back 5 more items, it's guaranteed that the vector will not reallocate memory when you do so.
To do that, the vector directly destroys the objects in the memory by explicitly calling the destructor, not by using delete.
If, perchance, somebody else were to write a container using contiguous storage roughly like a vector does (or some variant of that, like std::deque really does), you'd almost certainly want to use the same technique.
Just for example, let's consider how you might write code for a circular ring-buffer.
#ifndef CBUFFER_H_INC
#define CBUFFER_H_INC
template <class T>
class circular_buffer {
T *data;
unsigned read_pos;
unsigned write_pos;
unsigned in_use;
const unsigned capacity;
public:
circular_buffer(unsigned size) :
data((T *)operator new(size * sizeof(T))),
read_pos(0),
write_pos(0),
in_use(0),
capacity(size)
{}
void push(T const &t) {
// ensure there's room in buffer:
if (in_use == capacity)
pop();
// construct copy of object in-place into buffer
new(&data[write_pos++]) T(t);
// keep pointer in bounds.
write_pos %= capacity;
++in_use;
}
// return oldest object in queue:
T front() {
return data[read_pos];
}
// remove oldest object from queue:
void pop() {
// destroy the object:
data[read_pos++].~T();
// keep pointer in bounds.
read_pos %= capacity;
--in_use;
}
~circular_buffer() {
// first destroy any content
while (in_use != 0)
pop();
// then release the buffer.
operator delete(data);
}
};
#endif
Unlike the standard containers, this uses operator new and operator delete directly. For real use, you probably do want to use an allocator class, but for the moment it would do more to distract than contribute (IMO, anyway).
When you create an object with new, you are responsible for calling delete. When you create an object with make_shared, the resulting shared_ptr is responsible for keeping count and calling delete when the use count goes to zero.
Going out of scope does mean leaving a block. This is when the destructor is called, assuming that the object was not allocated with new (i.e. it is a stack object).
About the only time when you need to call a destructor explicitly is when you allocate the object with a placement new.
1) Objects are not created 'via pointers'. There is a pointer that is assigned to any object you 'new'. Assuming this is what you mean, if you call 'delete' on the pointer, it will actually delete (and call the destructor on) the object the pointer dereferences. If you assign the pointer to another object there will be a memory leak; nothing in C++ will collect your garbage for you.
2) These are two separate questions. A variable goes out of scope when the stack frame it's declared in is popped off the stack. Usually this is when you leave a block. Objects in a heap never go out of scope, though their pointers on the stack may. Nothing in particular guarantees that a destructor of an object in a linked list will be called.
3) Not really. There may be Deep Magic that would suggest otherwise, but typically you want to match up your 'new' keywords with your 'delete' keywords, and put everything in your destructor necessary to make sure it properly cleans itself up. If you don't do this, be sure to comment the destructor with specific instructions to anyone using the class on how they should clean up that object's resources manually.
Pointers -- Regular pointers don't support RAII. Without an explicit delete, there will be garbage. Fortunately C++ has auto pointers that handle this for you!
Scope -- Think of when a variable becomes invisible to your program. Usually this is at the end of {block}, as you point out.
Manual destruction -- Never attempt this. Just let scope and RAII do the magic for you.
To give a detailed answer to question 3: yes, there are (rare) occasions when you might call the destructor explicitly, in particular as the counterpart to a placement new, as dasblinkenlight observes.
To give a concrete example of this:
#include <iostream>
#include <new>
struct Foo
{
Foo(int i_) : i(i_) {}
int i;
};
int main()
{
// Allocate a chunk of memory large enough to hold 5 Foo objects.
int n = 5;
char *chunk = static_cast<char*>(::operator new(sizeof(Foo) * n));
// Use placement new to construct Foo instances at the right places in the chunk.
for(int i=0; i<n; ++i)
{
new (chunk + i*sizeof(Foo)) Foo(i);
}
// Output the contents of each Foo instance and use an explicit destructor call to destroy it.
for(int i=0; i<n; ++i)
{
Foo *foo = reinterpret_cast<Foo*>(chunk + i*sizeof(Foo));
std::cout << foo->i << '\n';
foo->~Foo();
}
// Deallocate the original chunk of memory.
::operator delete(chunk);
return 0;
}
The purpose of this kind of thing is to decouple memory allocation from object construction.
Remember that Constructor of an object is called immediately after the memory is allocated for that object and whereas the destructor is called just before deallocating the memory of that object.
Whenever you use "new", that is, attach an address to a pointer, or to say, you claim space on the heap, you need to "delete" it.
1.yes, when you delete something, the destructor is called.
2.When the destructor of the linked list is called, it's objects' destructor is called. But if they are pointers, you need to delete them manually.
3.when the space is claimed by "new".
Yes, a destructor (a.k.a. dtor) is called when an object goes out of scope if it is on the stack or when you call delete on a pointer to an object.
If the pointer is deleted via delete then the dtor will be called. If you reassign the pointer without calling delete first, you will get a memory leak because the object still exists in memory somewhere. In the latter instance, the dtor is not called.
A good linked list implementation will call the dtor of all objects in the list when the list is being destroyed (because you either called some method to destory it or it went out of scope itself). This is implementation dependent.
I doubt it, but I wouldn't be surprised if there is some odd circumstance out there.
If the object is created not via a pointer(for example,A a1 = A();),the destructor is called when the object is destructed, always when the function where the object lies is finished.for example:
void func()
{
...
A a1 = A();
...
}//finish
the destructor is called when code is execused to line "finish".
If the object is created via a pointer(for example,A * a2 = new A();),the destructor is called when the pointer is deleted(delete a2;).If the point is not deleted by user explictly or given a new address before deleting it, the memory leak is occured. That is a bug.
In a linked list, if we use std::list<>, we needn't care about the desctructor or memory leak because std::list<> has finished all of these for us. In a linked list written by ourselves, we should write the desctructor and delete the pointer explictly.Otherwise, it will cause memory leak.
We rarely call a destructor manually. It is a function providing for the system.
Sorry for my poor English!

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.