Я работаю в проекте C ++ 17, но мне нужно использовать C-legacy-library. Для этого мне нужно создать массив const char * в стиле C, но я борюсь с инициализацией. В частности,

#include <iostream>

int main(int argc, char* argv[])
{
    const int bound = 3;

    const char* inames[bound]{ "" };
    for(unsigned int i = 0; i < bound; i++) {
        const char *number = std::to_string(i).c_str();
        inames[i] = number;
    }

    for(unsigned int i = 0; i < bound; i++) {
        std::cout << "inames["
                  << std::to_string(i)
                  << "] = "
                  << inames[i]
                  << std::endl;
    }

    return 0;
}

Возвращает

inames[0] = 2
inames[1] = 2
inames[2] = 2

Как вывод, которого я не понимаю. Я ожидал, что результат будет

inames[0] = 0
inames[1] = 1
inames[2] = 2

Может ли кто-нибудь помочь мне указать на мою ошибку?

0
teekanne 13 Сен 2018 в 16:38

2 ответа

Лучший ответ

Проблема в том, что вам негде хранить сами строки, а только указатели на них.

Поступая таким образом, строки сохраняются в std :: strings, а на них ссылается простой массив C:

const int bound = 3;
std::vector<std::string> strings(bound);
const char* inames[bound];
for (unsigned int i = 0; i < bound; i++) {
    strings[i] =  std::to_string(i);
    inames[i] = strings[i].c_str();
}
1
Johnny Johansson 13 Сен 2018 в 13:51

Ваш код имеет неопределенное поведение .

std::to_string(i).c_str()

Вы создаете временный экземпляр std::string, а затем получаете его внутренний указатель const char*. В конце строки временный экземпляр мертв, поэтому указатель теперь болтается.

5
Vittorio Romeo 13 Сен 2018 в 13:40