#c #exception
#c #исключение
Вопрос:
Я знаю, что этот вопрос задавался много раз. Но в моем случае ошибка присутствует не всегда, поэтому я думаю, что это может быть по-другому. Я использую C , Visual Studio 2013, Windows 7 x64.
Вот соответствующий код:
void writeDATAToFile(const char *fname, string title, const VecDoubamp; spec_x, const VecDoubamp; spec_y, const VecDoubamp; freq)
{
ofstream of;
of.open(fname, ios_base::out);
if (!of.is_open())
{
return;
}
of << "somename" << endl;
of << "WAVES/S" << "t" << title << endl;
of << "BEGIN" << endl;
for (int i=0; i<spec_x.size(); i )
{
of << spec_x[i] << "ttt" << spec_y[i] << "ttt" << freq[i]<<endl;
}
of << "END" << endl;
of.close();
}
Предполагается, что эта функция записывает данные спектра (вычисленные ранее в программе) и записывает их в файл. Некоторые данные спектра не вызовут проблем, некоторые будут. Ошибка находится в цикле for.
Вот окно ошибки:
Комментарии:
1. И вы абсолютно уверены, что два других вектора всегда имеют точно такой же размер, как
spec_x.size()
? (И есть только одинfor
цикл, который я могу обнаружить, кстати)2. Когда вы говорите «Ошибка во втором цикле for», я вижу только один
3. Извините, да, есть только цикл for.
4. @student1: Докажите это утверждением.
5. Может ли нарушение доступа исходить из fname вместо этого? 😉
Ответ №1:
Вы передаете 3 вектора своей функции:
const VecDoubamp; spec_x, const VecDoubamp; spec_y, const VecDoubamp; freq
но вы никогда не проверяете, что они имеют одинаковый размер.
В вашем цикле (не во «втором» цикле, как вы сказали в своем вопросе, в опубликованном вами коде есть только один цикл) вы повторяете итерацию spec_x
и используете тот же индекс i
для индексации в два других вектора.
Что, если один или оба из ваших двух других векторов имеют меньший размер, чем spec_x
? Тогда вы индексируете вне пределов, что может вызвать ошибку, которую вы видите.
Комментарии:
1. примечание: Это нарушение доступа, а не исключение V . Я предполагаю, что это может не отображаться в режиме выпуска, например, с непроверенными итераторами….
2. Все они имеют одинаковую длину, но я перепроверю.
3. @doctorlove я не понимаю, что вы имеете в виду?
4. Когда я сказал V, я имел в виду C … опечатка. Это не исключение C , которое вы можете перехватить
5. @student1: вы можете прочитать о проверенных итераторах в msdn: msdn.microsoft.com/en-us/library/aa985965.aspx . Обратите внимание: Если _SECURE_SCL определено как 1, небезопасное использование итераторов вызывает ошибку времени выполнения, и программа завершается. Если определено как 0, проверенные итераторы отключены. По умолчанию значение _SECURE_SCL равно 0 для сборок выпуска и 1 для сборок отладки. Таким образом, по умолчанию итераторы проверяются для сборок отладки и не проверяются для сборок выпуска.
Ответ №2:
В сообщении об ошибке ясно говорится, что он пытается прочитать то, чего не должно быть.
Вы кодируете циклы таким образом:
for (int i=0; i<spec_x.size(); i )
{
of << spec_x[i] << "ttt" << spec_y[i] << "ttt" << freq[i]<<endl;
}
Это предполагает spec_x
, spec_y
и freq
имеют одинаковый размер.
- Вы можете проверить это перед циклом и выдать ошибку, если это предварительное условие не выполняется.
- Вы могли бы зациклиться на самом маленьком размере из всех трех.
- Вы могли бы оставить эту функцию как есть и поставить проверки там, где вы изначально заполняли данные.
Примечание — отладчик пытается вам помочь. Если вы нажмете «break», это вызовет у вас стек вызовов, и тогда вы сможете точно увидеть, какая переменная вызывает проблему.
Комментарии:
1. Спасибо, я еще раз проверю проблему с длиной и вернусь.