Почему происходит сбой с нарушением доступа к 0xcccccc ...? - PullRequest
0 голосов
/ 08 апреля 2010

У меня есть случайный кусок кода, который я использую для чтения из CSV-файлов ... и это нормально ... до тех пор, пока не произойдет примерно 2000 чтений ... тогда строка getline завершится ошибкой с нарушением доступа к 0xcccccc ... который Я предполагаю, означает, что входной поток (файл) был очищен ... Не то, что я знаю, почему:)

int CCSVManager::ReadCSVLine ( fstream * fsInputFile,
                               vector <string> * recordData )
{
    string s;

    getline ( *fsInputFile, s );
    stringstream iss( s );

    for ( unsigned int i = 0; i < getNumFields (); i++ )
    {
        getline ( iss, s, ',' );
        (*recordData)[i] = s;
    }

    return 0;
}

Есть идеи, почему?

Ответы [ 7 ]

5 голосов
/ 08 апреля 2010

std::vector не перераспределяет себя для расширения, когда вы обращаетесь к нему как массив, подобный этому. Что вы должны делать вместо

(*recordData)[i] = s;

есть

recordData->push_back(s);

Это расширит вектор по мере необходимости. Одно важное различие между этими двумя методами заключается в том, что первый всегда начинает писать с первого элемента вектора. Второй начнет добавляться в конец вектора, который отличается, если вектор изначально не пустой.

3 голосов
/ 08 апреля 2010

Вы уверены, что recordData имеет достаточно места для хранения всех записей? Это должно выглядеть так:

for ( unsigned int i = 0; i < getNumFields() && i < recordData->size() && getline(iss, s, ','); i++ ) 
 { 
  (*recordData)[i] = s; 
 }
2 голосов
/ 08 апреля 2010

Возможно, вы повреждаете память, если (*recordData).size() < getNumFields(). Попробуйте исключить getNumFields и полагаться на (*recordData).size() для хранения этой информации. Или вообще не устанавливайте размер вектора и используйте push_back.

Избегайте указателей тоже со ссылками.

int CCSVManager::ReadCSVLine ( fstream &fsInputFile, vector <string> &recordData )
{
 string s;

 getline ( fsInputFile, s );
 istringstream iss( s );

 for ( unsigned int i = 0; i < getNumFields (); i++ )
 {
  getline ( iss, s, ',' );
  recordData.push_back( s );
 }

 return 0;
    }
1 голос
/ 08 апреля 2010

вызов перед оператором for следующим образом, чтобы убедиться, что в векторе достаточно элементов.

recordData->resize(getNumFields ()); 
0 голосов
/ 08 апреля 2010

Argh ... Все очень хорошие ответы, но на самом деле это было что-то намного, намного, намного глупее. Благодаря вашим ответам я начал искать некоторые «другие» части кода и понял, что сделал неправильно :) (На самом деле передаваемый файл был пустым. Я не знал, что это повторное открытие файла каждый раз и перегружая файл вектором ... такая глупая ошибка :))

Спасибо за ваши ответы :) Все-таки я нашел свое решение:)

0 голосов
/ 08 апреля 2010

Я полагаю, что getNumFields() возвращает число, превышающее количество строк в файле.

Сколько строк / записей содержит файл?

Что возвращает getNumFields()?

0 голосов
/ 08 апреля 2010

- это getNumFields ();меняется.Похоже, его пересчитывают каждый раз.Переместить это из петли

...