deque push back error
Я пишу компилятор и использую deque для хранения меток методов класса и вот пример кода:
#include <deque>
#include <iostream>
#include <string>
using std::cout;
using std::deque;
using std::endl;
using std::string;
int main()
{
deque<const char *> names;
string prefix = "___";
const char *classname = "Point";
const char *methodname[] = {"Init", "PrintBoth", "PrintSelf", "equals"};
for (int i = 0; i < 4; i++)
{
string label = prefix + classname + "." + methodname[i];
names.push_back(label.c_str());
}
for (int i = 0; i < 4; i++)
cout << names[i] << endl;
return 0;
}
Однако результат не тот, который я ожидал:
___Point
___Point.PrintSelf
___Point.PrintSelf
___Point.equals
Кроме того, я заметил, что если просто отодвинуть имя метода назад
names.push_back(methodname[i])
Я получаю все имена методов в порядке.
Что я здесь не так сделал?
2 ответа
for (int i = 0; i < 4; i++)
{
string label = prefix + classname + "." + methodname[i];
names.push_back(label.c_str()); //what you're pushing? a temporary!
} //<--- `label` is destroyed here and it's memory is freed.
Вот label
переменная, которая уничтожается в закрывающей скобке и создается заново, в каждой итерации.
Это означает, что вы толкаете к names
это временное значение. Это вызывает проблему.
Я бы предложил вам использовать это:
std::deque<std::string> names;
затем сделайте это:
names.push_back(label); //a copy is pushed to the deque!
Это потому что string label
является временным, и его указатель chhar недействителен после выхода из области действия - в данном случае для цикла.
Я предлагаю использовать deque<string>
вместо. таким образом, вы можете подтолкнуть label
сама, а потом настоящая копия label
будет создан внутри deque.