27

I am new to C++. For a school project I need to make a function which will be able to return a string array.

Currently I have this in my header:

Config.h

string[] getVehicles(void);

Config.cpp

string[] Config::getVehicles(){
string test[5];
test[0] = "test0";
test[1] = "test1";
test[2] = "test2";
test[3] = "test3";
test[4] = "test4";

return test;}

Obviously this does not work but that's the idea of what I am trying to do. In Java this would be the way to do it. I've tried googling my problem but I didn't come across any answers that were clear to be honest.

A. Kootstra
  • 6,827
  • 3
  • 20
  • 43
sn0ep
  • 3,843
  • 8
  • 39
  • 63
  • When you are at, maybe also look at vectors. Easier to use. Because now the caller of getVehicles doesn't know the length of the array. – RvdK Sep 23 '11 at 10:10
  • use std::vector - first time I typed that today. There really needs to be a set of web pages with standard simple answers. Use std::vector, dont return address of locals etc. – pm100 Jan 25 '18 at 19:49

3 Answers3

31

Maybe it is better to use a vector in this case, but this is not a correct answer for the question. The reason why it doesn't work is that the variable test just exists in the scope of your function. So you have to manage the memory on your own. Here is an example:

string* getNames() {
 string* names = new string[3];
 names[0] = "Simon";
 names[1] = "Peter";
 names[2] = "Dave"; 

 return names;
}

In this case you return a pointer of the position in the heap. All the memory in the heap has to free manually. So it is now your work to delete the memory, if you don't need it anymore:

delete[] names;
Simon P
  • 382
  • 3
  • 9
  • 2
    Now, how do I find the length of returned array? – thefourtheye Aug 24 '13 at 03:48
  • Thank you, this solved my problem!, I was trying to solve this problem for hours, and my problem was I was declaring the string * names static instead of dynamic. – mp19uy Mar 25 '15 at 23:46
  • 1
    This doesn't answer the question either if the question is about how to implement the very same that Java would do. This code doesn't provide the garbage collection Java provides, the strings are not unicode, etc. etc. Returning a dynamically allocated array of strings is never the correct thing to do in C++ (unless you have a proven specific case). If you want Java use Java... if you want C++ use C++. Writing Java code in C++ is a very questionable (if not just plain stupid) approach. – 6502 Oct 17 '15 at 06:27
  • 1
    @thefourtheye In C++ and C, it is common practice to return the length of a returned array as a separate number (a `size_t`, since that is the standard unsigned integer type used here). So you would use a reference `size_t` in the arguments (`size_t& length`) since the return value is already the array. – Light Drake Feb 25 '17 at 18:09
  • use `std::vector` - you will be much happier – pm100 Jan 25 '18 at 21:10
19

In C++ you don't use an array, but a std::vector instance. Arrays in C++ must have a compile-time fixed length while std::vector instances can change their length at runtime.

std::vector<std::string> Config::getVehicles()
{
    std::vector<std::string> test(5);
    test[0] = "test0";
    test[1] = "test1";
    test[2] = "test2";
    test[3] = "test3";
    test[4] = "test4";
    return test;
}

std::vector can also grow dynamically, so in a C++ program you will find more often something like

std::vector<std::string> Config::getVehicles()
{
    std::vector<std::string> test; // Empty on creation
    test.push_back("test0"); // Adds an element
    test.push_back("test1");
    test.push_back("test2");
    test.push_back("test3");
    test.push_back("test4");
    return test;
}

Allocating dynamically an array of std::string is technically possible but a terrible idea in C++ (for example C++ doesn't provide the garbage collector that Java has).

If you want to program in C++ then grab a good C++ book and read it cover to cover first... writing Java code in C++ is a recipe for a disaster because the languages, despite the superficial braces similarity, are very very different in many fundamental ways.

Community
  • 1
  • 1
6502
  • 112,025
  • 15
  • 165
  • 265
0

Try this

#include <iostream>
#include <string>

using namespace std;

string * essai()
    {
    string * test = new string[6];
    test[0] = "test0";
    test[1] = "test1";
    test[2] = "test2";
    test[3] = "test3";
    test[4] = "test4";
    cout<<"test et *test\t"<<&test<<' '<<*(&test)<<'\n';
    return test;
    }

main()
    {
    string * toto;
    cout<<"toto et *toto\t"<<&toto<<' '<<*(&toto)<<'\n';
    toto = essai();
    cout<<"**toto\t"<<*(*(&toto))<<'\n';
    cout<<"toto\t"<<&toto<<' '<<*(&toto)<<'\n';
    for(int i=0; i<6 ; i++)
        {
        cout<<toto[i]<<' '<<&toto[i]<<'\n';
        }
    }

For example, in my computer, the result is

toto et *toto   0x7ffe3a3a31b0 0x55dec837ae20
test et *test   0x7ffe3a3a3178 0x55dec9ddd038
**toto  test0
toto    0x7ffe3a3a31b0 0x55dec9ddd038
test0 0x55dec9ddd038
test1 0x55dec9ddd058
test2 0x55dec9ddd078
test3 0x55dec9ddd098
test4 0x55dec9ddd0b8
 0x55dec9ddd0d8

Getting addresses and contents of addresses could help you to understand that an array in c++ is really rudimentary : it offers no methods and you could access an index without allocating memory (the value 6 in the loop). Your first example show a direct allocation of a local array (test), so you can't return it (the local array dies), in this example, the local variable dies also but there is always a variable that access at this part of allocated memory, the function, and then the variable that receive the result of the function, so the variable test is dead after the calling of the function but the memory is still allocated. Regards.

  • Don't forget to free memory after allocating it! Every line with "new" should have a line with "delete" to match. – Pillager225 Sep 20 '20 at 01:20