Возвращаемый массив строк в функции C ++ - PullRequest
17 голосов
/ 23 сентября 2011

Я новичок в C ++.Для школьного проекта мне нужно сделать функцию, которая сможет возвращать строковый массив.

В настоящее время у меня есть это в моем заголовке:

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;}

Очевидно, что это не работает, но это идея того, что я пытаюсь сделать.В Java это был бы способ сделать это.Я пытался погуглить мою проблему, но я не нашел ни одного ответа, который был бы честен.

Ответы [ 4 ]

26 голосов
/ 23 сентября 2011

Может быть, лучше использовать вектор в этом случае, но это не правильный ответ на вопрос.Причина, по которой это не работает, заключается в том, что переменная test просто существует в области действия вашей функции.Таким образом, вы должны управлять памятью самостоятельно.Вот пример:

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

 return names;
}

В этом случае вы возвращаете указатель позиции в куче.Вся память в куче должна быть освобождена вручную.Так что теперь ваша работа - удалить память, если она вам больше не нужна:

delete[] names;
12 голосов
/ 23 сентября 2011

В C ++ вы используете не массив, а экземпляр std::vector.Массивы в C ++ должны иметь фиксированную длину во время компиляции, в то время как экземпляры std::vector могут изменять свою длину во время выполнения.

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 также может динамически увеличиваться, поэтому в программах на C ++ вы найдете чащечто-то вроде

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;
}

Динамически выделять массив std::string технически возможно, но ужасная идея в C ++ (например, C ++ не предоставляет сборщика мусора, который есть в Java).

Если вы хотите программировать на C ++, тогда возьмите хорошую книгу по C ++ и прочитайте ее, чтобы покрыть сначала ... написание Java-кода на C ++ - это рецепт катастрофы, потому что языки, несмотря на внешнее сходство фигурных скобок,очень сильно отличаются во многих фундаментальных отношениях.

7 голосов
/ 23 сентября 2011

Используйте std::vector<std::string>.Гораздо проще работать с массивами C.

#include <string>
#include <vector>

...

std::vector<std::string> Config::getVehicles()
{
  std::vector<std::string> data;
  data.push_back("hello");
  ...
  return data;
}

Проверьте другие контейнеры в стандартной библиотеке, они почти всегда лучше, чем простые массивы в C ++.1009 * Если ваш метод getVehicles не изменяет состояние объекта Config, рассмотрите возможность сделать его const:

std::vector<std::string> Config::getVehicles() const { ... }
0 голосов
/ 27 апреля 2018

Попробуйте это

#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';
        }
    }

Например, на моем компьютере результат будет

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

Получение адресов и содержимого адресов может помочь вам понять, что массив в c ++действительно элементарно: он не предлагает методов, и вы можете получить доступ к индексу без выделения памяти (значение 6 в цикле).Ваш первый пример показывает прямое выделение локального массива (тест), поэтому вы не можете его вернуть (локальный массив умирает), в этом примере локальная переменная также умирает, но всегда есть переменная, которая обращается к этой частивыделенная память, функция, а затем переменная, которая получает результат функции, поэтому проверка переменной теряет силу после вызова функции, но память все еще выделяется.С уважением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...