Here is my problem. I have a function that takes struct
as input, allocates a new struct
and then returns it. The struct
has the following contents
struct Data {
std::vector<custom_type> vector_vars;
std::string key;
std::map<std::string, Data*> index;
};
vector_vars
is of size 500-1000. custom_type if relevant is this class. The index
helps me access different Data
struct by key
. This is the function.
Data func(Data inputData) {
Data outputData;
//compare values with inputData
//change some values in Data struct
return outputData
}
Do I use stack allocation and return it so that it is copied to RHS. Is this advisable since copying may create a lot of overhead?
Can I return a reference/pointer to struct allocated on the stack within a function?
Is it advisable to use dynamic allocation instead here (may be with std::shared_ptr
) for efficiency?
There are two ways of "returning a structure." You can return a copy of the data, or you can return a reference (pointer) to it. It's generally preferred to return (and pass around in general) a pointer, for a couple of reasons. First, copying a structure takes a lot more CPU time than copying a pointer.
A struct can be either passed/returned by value or passed/returned by reference (via a pointer) in C. The general consensus seems to be that the former can be applied to small structs without penalty in most cases.
You can return a structure from a function (or use the = operator) without any problems. It's a well-defined part of the language.
Return struct from a functionThe function returns a structure of type struct student . The returned structure is displayed from the main() function. Notice that, the return type of getInformation() is also struct student .
Return the object by value. Copy elision is an optimization that the standard allows compilers to make that removes unnecessary copies. In C++03, the copy will almost certainly be elided by the compiler. In C++11, the copy will first be considered as a move (which will in turn move its contents) and even that may be elided.
in a
return
statement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function or catch-clause parameter) with the same cv-unqualified type as the function return type, the copy/move operation can be omitted by constructing the automatic object directly into the function’s return value
Specifically, when this criteria results in copy elision, it is commonly known as named return value optimization, a form of return value optimization.
So the most idiomatic and performance-friendly option here is to return by value. Of course, if you measure that even under optimization returning by value is a problem, then sure, you may consider dynamically allocating (see point 3).
No, you should not return a reference or pointer to a local variable. The object with automatic storage duration (what you refer to as allocating on the stack) will not exist any more. The reference or pointer will be left dangling. Using it in any meaningful way will result in undefined behaviour.
No, as mentioned above, it is advisable to return by value. However, if you really, really need to, you may dynamically allocate your Data
and return it by smart pointer. The preferred smart pointer here would be a std::unique_ptr
as your function is passing ownership to the calling function (not sharing ownership).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With