2016-12-23 5 views
0

Иногда я получаю этот тип ошибок. Мой вопрос в том, есть ли способ узнать информацию о том, когда и где (какая строка) именно эта ошибка возникает? Я нахожусь на ubuntu linux 14.04. Использование sublime и g ++.Исключения с плавающей запятой, ошибки сегментации и аналогичные ошибки

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

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

int main() 
{ 
    vector<int> firstVector; 
vector<int> secondVector; 
firstVector = {2,4}; 
secondVector = {16,32,96}; 
auto it = firstVector.begin(); 
for (int i = 1; i <= 100; ++i) 
{ 
    it = firstVector.begin(); 
    for (; ; ++it) 
    { 
     if(i%(*it)!=0) 
      break; 
     if(it==firstVector.end()) 
     { 
      it=secondVector.begin(); 
      while(it!=secondVector.end()) 
      { 
       if((*it)%i!=0) 
       { 
        it=firstVector.begin(); 
        break; 
       } 
       it++; 
      } 
     } 
     if(it==secondVector.end()) 
      break; 
    } 
    if(it==secondVector.end()) 
     cout << i << endl; 
} 
return 0; 
} 
+5

Добро пожаловать на переполнение стека! Похоже, вам, возможно, потребуется научиться использовать отладчик для выполнения вашего кода. С хорошим отладчиком вы можете выполнить свою программу по очереди и посмотреть, где она отклоняется от ожидаемого. Это важный инструмент, если вы собираетесь заниматься программированием. Дальнейшее чтение: ** [Как отлаживать небольшие программы] (http://ericlippert.com/2014/03/05/how-to-debug-small-programs/) ** – NathanOliver

+0

Где ваши тестовые данные? И если у вас это есть, жестко запрограммируйте данные в программе, а не используйте 'cin' и вынимайте клавиатуру каждый раз, когда программа запускается. – PaulMcKenzie

+0

Я не уверен, почему я не использовал тестовые данные. Никогда не нуждался в этом, я думаю? Кроме того, это решение для вызова кода, следовательно, «cin». – zeke

ответ

1

Я предполагаю, что есть проблема в итерации над firstVector и secondVector. Во втором цикле:

auto it = firstVector.begin(); 
for (; ; ++it) 
{ 

it является итератора для firstVector. Но в следующем цикле:

it=secondVector.begin(); 
while(it!=secondVector.end()) 
{ 

it становится итератор для secondVector. Итерация над it продолжается во внешнем for контурах после этого цикла while. Вы увеличиваете ++it и элементы доступа if(i%(*it)!=0) в момент и после элемента .end(). Это приводит к UB:

Этот элемент действует как заполнитель; попытка доступа к нему приводит к неопределенному поведению.

+0

Это было великолепное редактирование. Я пытался понять так сильно, что вы говорили. – zeke

+0

@ yavuz650 Да, надеюсь, что это не более ясно. – Nikita

+0

Проверьте обновленный код. Для каждой итерации крайнего «за» цикла «он» переназначается на firstVector.begin(). Если цикл while заканчивается, потому что «он» достигает .end(), тогда программа также выходит из цикла «for» в середине (контрольная строка 39). Я здесь в недоумении. – zeke

0

Этот вопрос является разновидностью двухпартова. Поскольку Никита уже обращался к вашему коду ...

Вопрос в том, есть ли способ узнать информацию о том, когда и где (в какой строке) именно эта ошибка возникает?

Использовать gdb name-of-executable для отладки в Linux. Просто run, и программа сломается, когда произойдет сбой seg, или, я считаю, выдается фатальное исключение. Он укажет вам имя файла и номер строки.

Вы также можете посмотреть другие команды GDB, как здесь: http://www.yolinux.com/TUTORIALS/GDB-Commands.html

+1

Обязательно компилируйте с помощью '-O0', чтобы номера строк не оптимизировались. – Matt

Смежные вопросы