Ошибка сегментации (C++ в ubuntu 16.04)

403
05 февраля 2017, 12:55

Программа выдаёт ошибку сегментации при обращении к последнему элементу двумерного массива в цикле его обработки. Более того, она имеет странные значения x и y в начале(но это вопрос второстепенный). Странно так же и то, что я продумал вариант выхода за границы массива, но ошибка происходит при обращении к последнему элементу. Есть подозрение на ошибку в реализации механики цикла for, но это как-то слишком странно и даже не верится... В чём может быть ошибка? Код (да, ошибку искал cout'ами, не бейте) Забавен тот факт, что из for в нужный момент программа не производит выход. Не делать же железобетонную проверку переменных - итераторов x и y на их значения... Из-за чего возникает сегфолт?

#include <cstdlib>
#include <iomanip>
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
    const int X = 10;
    const int Y = 10;
    int field[X][Y];
    int n = 0; //итератор для перечисления одномерных массивов
    int x, y, x_sec = 0;
    //x_iterator = X - 1;
    //y_iterator = Y - 1;
    int point_x[10],
        point_y[10]; //массивы в которые определяются координаты точек.
    for (x = 0; x < X; x++)
    {
        for (y = 0; y < Y; y++)
        {
            field[x][y] = rand() % 2;
            cout << setw(6) << left << field[x][y];
        }
        cout << endl;
    }
    cout << x << " " << y << " " << endl;
    for (x = 0; x < X; //изначально было x<=X И y<=Y соответственно, что давало явный вылет. Ситуация от смены условий на строгие не поменялась.
            x++) // цикл обработки. тут возникает ошибка при условии что x = 10
    {
        cout << "debug point 1" << endl;
        for (y = 0; y < Y; y++) //и y = 10
        {
            cout << "x = " << x << " y = " << y << endl;
            cout << "debug point 2" << endl;
            if (field[x][y] >
                    0) //захват первой точки. Если она есть, то в point_x, point_y [n] пишутся координаты ненулевого элемента
            {
                cout << "адрес массива - " << x << " " << y << endl;
                cout << "debug point 3" << endl;
                point_x[n] = x;
                point_x[n] = y;
                n++;
                cout <<  "N = " << n << " point x = " << point_x[n] << " point y =" <<
                     point_y[n] <<  endl;
                cout << "debug point 4" << endl;
                for (x_sec = x; x_sec < X - 1; x_sec++)
                {
                    cout << "адрес подмассива(s_sec) " << x_sec << " " << y << endl;
                    cout << "debug point 5" << endl;
                    if (field[x_sec][y] > 0)
                    {
                        cout << "debug point 6" << endl;
                        point_x[n] = x_sec;
                        point_y[n] = y;
                        n++;
                        cout << "x_sec = " << x_sec << " y = " << y << endl;
                        cout << "debug point 7 | N = " << n << " point x = " << point_x[n] <<
                             " point y =" << point_y[n] <<  endl;
                    }
                }
            }
            else
            {
                cout << "debug point 8" << endl;
                n = 0;
                point_x[n] = 0;
                point_y[n] = 0;
                cout << "debug point 9 " << x << " " << y << endl;
            }
            cout << "x = " << x << " y = " << y << endl;
            cin.get();
        }
    }
    cout << point_x[0] << " " << point_y[0];
    return 0;
}
Answer 1

Внесу свою лепту. Посмотрите внимательно на этот участок кода:

        point_x[n] = x;
        point_x[n] = y;
        n++;
        cout <<  "N = " << n << " point x = " << point_x[n] << " point y =" <<
             point_y[n] <<  endl;

Во-первых, полагаю, что во второй строке вы хотели написать point_y[n] = y, но закрался коварный copy-paste. Получилось, что вы дважды переписываете один и тот же участок памяти.

Во-вторых, выражение n++ инкрементирует значение индекса n, а значит в следующей строке происходит обращение уже к следующему элементу массива. На последней итерации цикла это приводит к выходу за пределы массива. Правильно было бы написать так:

int prev = n++;
cout << "N = " << prev << " point x = " << point_x[prev] << " point y =" <<
         point_y[prev] << endl;

Заметьте, таких проблемных участков в вашем коде несколько.

Answer 2

У вас все массивы размера 10, т.е. с индексами от 0 до 9. А вот в этих циклах вдруг

for (x = 0; x <= X; x++)
    for (y = 0; y <= Y; y++)

идет доступ по индексам 10 из-за нестрогого сравнения <=. Это явный вылет за пределы массива.

При этом в цикле ввода у вас все сделано правильно (сравнения в условиях циклов строгие), а здесь вдруг почему-то стало x <= X и y <= Y. Почему?

READ ALSO
Работа функции std::time()

Работа функции std::time()

Что будет с функцией std::time(0), когда количество секунд, прошедших с 1970 года превысит максимально возможное хранимое число в возвращаемом типе?

422
Русский язык в JSON

Русский язык в JSON

Вычитал из этой статьи, что есть парсер JSONУдобный парсер, но при вводе значений на русском языке выводится ошибка

1203