Reputation: 503
I am a C++ noob and I wanna know how can i return an array from a C++ function.
I tried the following code but doesn't seem to work.
char some_function(){
char my_string[] = "The quick brown fox jumps over the lazy dog";
return my_string;
}
Upvotes: 4
Views: 1455
Reputation: 56088
There are two ways to do this without STL. One is using an 'out' parameter, and the other is by abusing a structure. Here is how the first works:
#include <cstddef> // For ::std::size_t
#include <cstring> // For strncpy
void some_function(char retval[], ::std::size_t retval_len) {
char my_string[] = "The quick brown fox jumps over the lazy dog";
::std::strncpy(retval, my_string, retval_len);
}
Here is how the second would work:
struct array_struct {
char the_array[50];
};
array_struct some_function() {
array_struct ary = { "The quick brown fox jumps over the lazy dog" };
return ary;
}
Upvotes: 0
Reputation: 620
That's because the variable you are trying to return from the function call is a temporary variable which is created in stack and the stack variables are cleared once the control comes out of the block. So the pointer you have returned points to a variable which has been deleted.
One of the alternative if you want to return something from a function is you pass an address that function and put the variable in that address
void some_function(string& some_string){
char my_string[] = "The quick brown fox jumps over the lazy dog";
some_string = my_string;
}
Upvotes: 0
Reputation: 138251
This will crash because of the memory model.
In C++ (as in many other languages), there are two two popular places where you can allocate memory: the stack and the heap.
In C++, the stack is a special memory region where functions place whatever values they'll need during their execution. The most important thing to remember is that whatever lives there gets deleted once the function returns. That means that if you return a pointer to something on the stack, your program is bound to crash because whatever was there isn't anymore. That's what you'd be doing if you returned an array.
Hopefully, there's a place where data can live forever ("forever" being the duration of your program): the heap. If you allocate something on the heap, it won't get cleared away when the function returns. However, it implies additional bookkeeping, since you could easily lose all references to a certain block of allocated memory; and if you do, there's no way to reclaim it (that's called a leak, and it's a very bad thing). Therefore, a rule was suggested: if a function allocates memory on the heap, it should be responsible for freeing it. Problem is, if your function returns allocated memory, it obvisouly can't dispose of it. Therefore, you shouldn't allocate memory on the heap and return it.
So, if you can't allocate your array on the stack, and you can't return a pointer to memory on the heap, what can you do?
I suggest you use C++ types to solve your problem. If you're about to use an array of characters, the best would be a std::string
(#include <string>
). If you're about to use an array of whatever else, the best would probably be a std::vector<YourTypeHere>
(#include <vector>
). Both manage their own memory, and therefore it's safe to return them.
There's ample documentation for both on here and Google. Here's a quick example anyways.
std::vector<int> foo()
{
std::vector<int> my_vector;
my_vector.push_back(1);
my_vector.push_back(2);
my_vector.push_back(3);
return my_vector;
}
std::string bar()
{
std::string my_string = "The quick brown fox jumps over the lazy dog";
return my_string;
}
int main()
{
std::vector<int> my_vector = foo();
// will print 123
std::cout << my_vector[0] << my_vector[1] << my_vector[2] << std::endl;
std::string my_string = bar();
// will print The quick brown fox jumps over the lazy dog
std::cout << my_string << std::endl;
}
Upvotes: 0
Reputation: 156278
if you can use a standard container, then you should. In your specific example, the container you should use is std::string
, as:
#include <string>
std::string some_function(){
std::string my_string = "The quick brown fox jumps over the lazy dog";
return my_string;
}
If, on the other hand, you really need to pass around an actual array, you have to do things a bit more to do. most likely the best choice is to let the caller work out the details of the array, and just pass that as an argument to the callee: this would look like so:
// notice here that we use 'string.h', with the '.h' extension, different from above
#include <string.h>
void some_function(size_t len, char * dest)
{
std::strncpy(dest, "The quick brown fox jumps over the lazy dog", len);
}
int main()
{
const std::size_t stringSize = 100;
char myString[stringSize];
some_function(stringSize, myString);
}
Another option, though even less desirable in many cases, is to allocate a new area of storage to hold the array.
char* some_function()
{
char* result = new char[44];
strcpy(result, "The quick brown fox jumps over the lazy dog");
return result;
}
int main()
{
char *myString = some_function();
// do some stuff with myString
delete myString[];
}
Upvotes: 1
Reputation: 35990
The reason that code isn't working is that the minute the function ends, so does the lifetime of the string you have created. Instead, if you're going to be working in C++ use std::string
and return that.
std::string myFunc(){
return string("hey a new string");
}
For other arrays use std::vector
, std::deque
or one of the other STL classes. I'd also point you to look at the STL (standard template library):
vector<float> myFunc(){
vector<float> blah;
blah.push_back(4.5);
blah.push_back(5.7);
return blah;
}
On returning arrays:
The big problem with pointers and such is object lifetime considerations. Such as the following code:
int* myFunc(){
int myInt = 4;
return &myInt;
}
what happens here is that when the function exits myInt
no longer exists leaving the pointer that was returned to be pointing at some memory address which may or may not hold the value of 4. If you want to return an array using pointers (I really suggest you don't and use std::vector
) it'll have to look something like:
int* myFunc(){
return new int[4];
}
which uses the new operator.
Upvotes: 5
Reputation: 141958
In C++ it is better to use std::string
over an array of char
in almost every case.
More generally, consider the STL container classes rather than C-style arrays.
Here are a couple of examples...
#include <string>
#include <vector>
std::string some_function()
{
return "The quick brown fox jumps over the lazy dog";
}
std::vector<std::string> some_other_function()
{
std::vector<std::string> stuff;
stuff.push_back("Spam");
stuff.push_back("Spam");
stuff.push_back("Spam");
stuff.push_back("Spam");
stuff.push_back("Spam");
stuff.push_back("Spam");
stuff.push_back("Spam");
return stuff;
}
Upvotes: 2