C ++ возвращает указатель из функции. Значения потеряны - PullRequest
5 голосов
/ 20 июня 2011

У меня есть следующее:

void Class1::method()
{
  QStringList* file_list;
  collect_file_paths(file_list);    //Sends pointer to the method below
}

void Class1::collect_file_paths(QStringList* file_list)
{
  //Gather file paths
  DirectorySearch ds;
  connect(&ds, SIGNAL(updateStatus(QString)), this, SLOT(onStatusUpdate(QString)));
  file_list = ds.get_file_names(_strPath);  //Returns a pointer of QStringList
}

QStringList* DirectorySearch::get_file_names(QString path)
{
  QStringList *file_names = new QStringList;
  traverse(path, file_names);
  compare_existing(file_names);
  return file_names;  //returning pointer address
}

Что происходит, так это то, что адрес памяти, возвращаемый с get_file_names(), теряется / удаляется, когда я покидаю область действия Class1::collect_file_paths(). Насколько я понимаю, QStringList *file_names = new QStringList; в классе DirectorySearch теперь в куче памяти. Таким образом, это должно быть оставлено в куче, пока я не назову delete, то есть это никогда не выходит за рамки. Однако, как упоминалось выше, адрес / значения QStingList теряются, когда я возвращаюсь к Class1::method() из collect_file_paths(file_list).

Кто-нибудь может объяснить, что происходит?

Спасибо.

Ответы [ 5 ]

7 голосов
/ 20 июня 2011

Когда вы делаете file_list = ds.get_file_names(_strPath); //Returns a pointer of QStringList , вы изменяете значение file_list (ячейка памяти 32 / 64b), НЕ значение данных, которые представляет ячейка памяти.

Вам необходимо передать ссылку на указатель (или указатель на указатель)

void Class1::method()
{
  QStringList* file_list;
  collect_file_paths(&file_list);    //Sends pointer to pointer to the method below
}

void Class1::collect_file_paths(QStringList** file_list)
{
  //Gather file paths
  DirectorySearch ds;
  connect(&ds, SIGNAL(updateStatus(QString)), this, SLOT(onStatusUpdate(QString)));
  *file_list = ds.get_file_names(_strPath); //set value of pointer in caller to value returned by below function
}
...

или около того

2 голосов
/ 20 июня 2011

Ваш метод collect_file_paths не изменяет указатель file_list каким-либо видимым способом.Когда вызывается collect_file_paths, ему присваивается адрес памяти (указатель) QStringList.Если бы вы присвоили переменную file_list, вы просто указали бы на другой QStringList, но вызывающие абоненты не могли бы это увидеть.

Это как если бы вы написали следующее:

void foo(int a)
{
  /* Callers will not see this change. */
  a = 5;
}

Что вам нужно сделать, это передать указатель на указатель:

void collect_file_paths(QStringList **file_list)
{
  *file_list = ...
}

void foo()
{
  QStringList *file_names;
  collect_file_paths(&file_names);
}
1 голос
/ 20 июня 2011

Комментарий:

  collect_file_paths(file_list);    //Sends pointer to the method below

неверно: вызов копирует указатель на аргументы метода.

Итак, строка:

file_list = ds.get_file_names(_strPath);  //Returns a pointer of QStringList

Ничего не влияет на значение в методе method().

1 голос
/ 20 июня 2011

Метод get_file_names() в порядке. Ваша проблема - collect_file_paths(). Указатель file_list скопирован в функцию, поэтому присвоение ему в пределах collect_file_paths не влияет на переменную file_list в method.

Один из вариантов - использовать ссылку на указатель:

void Class1::collect_file_paths(QStringList*& file_list) ...

Или, как предлагают другие, просто передайте ссылку на сам список и действуйте в соответствии с этим.

0 голосов
/ 20 июня 2011

Вам необходимо вернуть результат по ссылке:

void Class1::collect_file_paths(QStringList& file_list)
{
  //Gather file paths
  DirectorySearch ds;
  connect(&ds, SIGNAL(updateStatus(QString)), this, SLOT(onStatusUpdate(QString)));
  file_list = ds.get_file_names(_strPath);  //Returns a pointer of QStringList
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...