Ошибка сегментации при попытке разыменовать указатель из вектора указателей

У меня есть вектор указателей на объекты, которые я повторяю, используя std::vector::iterator`. Поскольку возвращаемый элемент сам является указателем, я дважды разыменовываю итератор: один раз, чтобы вернуть указатель, и один раз, чтобы преобразовать указатель в фактический объект.

Я пытаюсь вызвать функцию-член (getClass), которая возвращает std::string, и я пробовал как (**it).getClass(), так и (*it)->getClass(), но оба дают мне ошибку сегментации. Я продолжаю чувствовать, что упускаю что-то очевидное.

частичный код функции:

void dataSet::createFolds()
{
   // Shuffle the data vector
   std::random_shuffle( m_records.begin(), m_records.end());

   std::cout << "STARTING MAIN LOOP.  THERE ARE " << m_records.size() << " RECORDS\n";
   // iterate through the data vector and assign each to a fold
   std::vector<dataRecord *>::iterator it = m_records.begin();
   while (it != m_records.end())
   {
      std::string currentClass = (*it)->getClass();  // SEG FAULT HERE
      .
      .
      .
   }
   .
   .
   .
}

Вектор: m_records... код

dataRecord определяется следующим образом... код

В ответ на вопросы о заполнении вектора:

Данные считываются из текстового файла, и я действительно не хочу публиковать все это, если мне не нужно (212 строк), но соответствующий код для заполнения вектора приведен ниже. Конструктор объекта dataRecord принимает вектор объектов поля. Я использую временный указатель, использую new для создания объекта, а затем push_back указатель.

while ...
{
   std::vector<field> fields;

   // build the fields vector
   for (unsigned int i = 0; i < numAttribs; ++i)
      fields.push_back(field(data.at(i), attribTypes[i]));

   // create the new dataRecord
   dataRecord * newRecord = new dataRecord(fields);

   // add the record to the set
   m_records.push_back(newRecord);

   ++recordNum;
   std::cout << "read record " << recordNum << std::endl;
}

person Matt    schedule 04.10.2011    source источник
comment
Похоже, ошибка связана с тем, как вы заполняете вектор. Опубликуйте соответствующий код, и мы можем посмотреть.   -  person Kerrek SB    schedule 04.10.2011
comment
Ваши определения хороши, но я думаю, что проблема кроется в другом. Может быть, в то время вы заливаете вектор? Вы на 100% уверены, что не вставляете в вектор никаких NULL?   -  person Constantinius    schedule 04.10.2011
comment
Может ли один или несколько ваших указателей болтаться, то есть указывать на что-то, что было уничтожено?   -  person Fred Larson    schedule 04.10.2011
comment
Я предполагал, что проблема была с разыменованием, так как пошаговое выполнение с помощью gdb рухнуло прямо тогда. Я пройдусь по конструктору и проверю, что помещается в вектор, и состояние всех задействованных объектов.   -  person Matt    schedule 04.10.2011
comment
Проходя через gdb, он правильно заполняет m_records. Нулевых элементов точно нет.   -  person Matt    schedule 04.10.2011
comment
Проблема в коде, который вы нам не показали. Пожалуйста, создайте минимальную полную примерную программу и опубликуйте ее в своем вопросе. В процессе создания образца вы можете обнаружить ошибку самостоятельно. См. sscce.org.   -  person Robᵩ    schedule 04.10.2011
comment
замена всего ввода файла статическими значениями, похоже, решает проблему. Я думаю, это процесс исключения отсюда   -  person Matt    schedule 04.10.2011


Ответы (4)


На мой взгляд, элементы вектора плохо инициализированы. Возможно, вам нужно протестировать код, который заполняет вектор, независимо, прежде чем тестировать их извлечение. Извините за мой английский ;)

person Santana6.35    schedule 04.10.2011

Либо указатели в ваших контейнерах нулевые, либо они являются висящими указателями на освобожденную память.

Дважды проверьте код, который заполняет m_records.

person jpalecek    schedule 04.10.2011

In

std::string dataRecord::getClass() {return m_data.at(m_data.size() - 1).getTextData();}

Вы должны проверить m_data.size(), потому что он может быть равен 0, поэтому вы получите исключение вне диапазона.

person Tio Pepe    schedule 04.10.2011

// create the new dataRecord
   dataRecord * newRecord = new dataRecord(fields);

Я предполагаю, что ошибка в конструкторе dataRecord. Вы уверены, что он делает свою работу должным образом?

person jrok    schedule 04.10.2011
comment
Поля — это вектор полевых объектов, а не другая запись данных, поэтому это не конструктор копирования. - person Matt; 04.10.2011