Segmentation fault при вызове метода mock-объекта

265
19 сентября 2017, 08:37

Есть класс ITable, содержащий чисто виртуальный метод columnAt:
virtual Column &columnAt(int index) = 0;
Его наследником является класс MockTable. Он содержит строку MOCK_METHOD1(columnAt, Column&(int));
В методе SetupTestCase() класса TestDialogCreator задал поведение при вызове метода columnAt() (id, name, value, flag - структуры типа Column):

ON_CALL(*schema, columnAt(0)).WillByDefault(ReturnRef(id));
ON_CALL(*schema, columnAt(1)).WillByDefault(ReturnRef(name));
ON_CALL(*schema, columnAt(2)).WillByDefault(ReturnRef(value));
ON_CALL(*schema, columnAt(3)).WillByDefault(ReturnRef(flag));

В коде теста задал ожидание того, что метод будет вызван для аргументов i=0..3 по одному разу:

EXPECT_CALL(*schema, columnAt(0)).Times(Exactly(1)); // 4 строки  

После этого вызвал метод DialogCreator::makeDialog(ITable * const schema). Отрывок из его кода:

QDialog *DialogCreator::makeDialog(ITable * const schema)
  {
    dialog = new QDialog();
    QVBoxLayout *dialogLayout = new QVBoxLayout(dialog);
    dialog->setLayout(dialogLayout);
    for(size_t i = 0; i < schema->columnCount(); ++i)
    {
      Column column = schema->columnAt(i);
      // ...
    }
  // ...
  }  

При вызове columnAt(i) получил segmentation fault.
Содержимое стека:

1  std::__atomic_base<int>::load
2  QAtomicOps<int>::load<int>
3  QBasicAtomicInteger<int>::load
4  QtPrivate::RefCount::ref
5  QString::QString
6  Db::Column::Column
7  Db::DialogCreator::makeDialog 

При этом, если везде заменить ссылку на объект, т.е. метод virtual Column columnAt(int index) = 0; и т.д., то падения нет. В чем может быть проблема и как починить, оставив при этом ссылки (если возможно)?

Answer 1

Судя по всему, проблема была в том, что структуры Column были созданы на стеке и были уничтожены при выходе из функции. Сделал их static-полями класса TestDialogCreator - и все заработало.

READ ALSO
Что происходит при выделения памяти под объект класса?

Что происходит при выделения памяти под объект класса?

Допустим, есть у меня класс BaseAУ него есть виртуальные и статические методы, а так же конструктор с деструктором

230
QFileDialog имя расположение файла char*

QFileDialog имя расположение файла char*

При вызове QFileDialog::getOpenFileName, и попытке преобразования QString в char* или же const char*, происходит либо потеря данных, или что-то еще нехорошее, и VLC отказывается...

295
Написать и вызвать функцию с переменным количеством параметров

Написать и вызвать функцию с переменным количеством параметров

Задача есть, нужно отдельно задать функцию со сменным числом параметров, а потом ее вызвать

242