C++ correct way to return pointer to array from function
Your code is OK. Note though that if you return a pointer to an array, and that array goes out of scope, you should not use that pointer anymore. Example:
int* test (void)
{
int out[5];
return out;
}
The above will never work, because out
does not exist anymore when test()
returns. The returned pointer must not be used anymore. If you do use it, you will be reading/writing to memory you shouldn't.
In your original code, the arr
array goes out of scope when main()
returns. Obviously that's no problem, since returning from main()
also means that your program is terminating.
If you want something that will stick around and cannot go out of scope, you should allocate it with new
:
int* test (void)
{
int* out = new int[5];
return out;
}
The returned pointer will always be valid. Remember do delete it again when you're done with it though, using delete[]
:
int* array = test();
// ...
// Done with the array.
delete[] array;
Deleting it is the only way to reclaim the memory it uses.
Your code as it stands is correct but I am having a hard time figuring out how it could/would be used in a real world scenario. With that said, please be aware of a few caveats when returning pointers from functions:
- When you create an array with syntax
int arr[5];
, it's allocated on the stack and is local to the function. - C++ allows you to return a pointer to this array, but it is undefined behavior to use the memory pointed to by this pointer outside of its local scope. Read this great answer using a real world analogy to get a much clear understanding than what I could ever explain.
- You can still use the array outside the scope if you can guarantee that memory of the array has not be purged. In your case this is true when you pass
arr
totest()
. - If you want to pass around pointers to a dynamically allocated array without worrying about memory leaks, you should do some reading on
std::unique_ptr
/std::shared_ptr<>
.
Edit - to answer the use-case of matrix multiplication
You have two options. The naive way is to use std::unique_ptr
/std::shared_ptr<>
. The Modern C++ way is to have a Matrix
class where you overload operator *
and you absolutely must use the new rvalue references
if you want to avoid copying the result of the multiplication to get it out of the function. In addition to having your copy constructor
, operator =
and destructor
, you also need to have move constructor
and move assignment operator
. Go through the questions and answers of this search to gain more insight on how to achieve this.
Edit 2 - answer to appended question
int* test (int a[5], int b[5]) {
int *c = new int[5];
for (int i = 0; i < 5; i++) c[i] = a[i]+b[i];
return c;
}
If you are using this as int *res = test(a,b);
, then sometime later in your code, you should call delete []res
to free the memory allocated in the test()
function. You see now the problem is it is extremely hard to manually keep track of when to make the call to delete
. Hence the approaches on how to deal with it where outlined in the answer.