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.

Другие вопросы по тегам