Ошибка при переписывание кода в функции

140
29 ноября 2021, 02:00

Попалась вот такая задача:

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

Моя реализация, которая работает:

#include <iostream> 
#include <iomanip> 
#include <ctime> 
using namespace std;
int main()
{
    const int m = 100, n = 100;
    setlocale(LC_ALL, "Russian");
    int n1, n2; // n- столбцы, m -строки 
    cout  <<  "Введите размерность массива m х n: \n";
    cin  >> n1 >> n2;
    int y1;
    cout  <<  "Введите нижний предел для генерации случайных чисел: \n";
    cin  >>  y1;
    int y2;
    cout  <<  "Введите верхний предел для генерации случайных чисел: \n";
    cin  >>  y2;
    int x[m][n];
    srand(time(0));
    for (int i = 0; i < n1; i++)
        for (int j = 0; j < n2; j++)
            x[i][j] = y1 + rand() % (y2 - y1 + 1);
    cout  <<  "Исходный массив: \n";
    for (int i = 0; i < n1; i++) {
        for (int j = 0; j < n2; j++)
            cout  <<  x[i][j]  <<  "\t";
        cout  <<  "\n";
    }
    int* l;
    int* h;
    l = (int*)malloc(n1 * sizeof(int));
    h = (int*)malloc(n2 * sizeof(int));
    int k = 0;
    for (int i = 0; i <= n1; i++)
        if (x[i][0] % 2 != 0) k++;
    int ch = 0;
    for (int i = 0; i <= n2; i++)
        if (x[0][i] % 2 == 0)
        {
            for (int j = 0; j < n2; j++)
                x[n1 + ch][j] = x[0][i];
            ch++;
        }
    if (k < n2)
    {
        n1 = n1 + ch - 1;
        n2 = n2 - k;
        l = (int*) realloc(l, (int)n1);
        h = (int*) realloc(h, (int)n2);
        cout  <<  "\nРезультирующий массив: \n";
        for (int i = 0; i < n1; i++) {
            for (int j = 0; j < n2; j++)
                cout  <<  x[i][j]  <<  "\t";
            cout  <<  "\n";
        }
    }
    else cout  <<  "\n Обработать невозможно \n";
    system("pause");
    return 0;
}

Пытался переделать в функции, но это не работает.

#include <iostream> 
#include <iomanip> 
#include <ctime> 
using namespace std;
//Прототипы функций 
int** create_array(int n1, int n2, int y3, int y4);
void print_array(int n1, int n2, int** a);
//Нахождение количества нечетных чисел в 1 ст в динамическом массиве размера n 
int count_even_numbers(int* b, int n);
//Нахождение количества четных чисел в 1 стр в динамическом массиве размера n 
int count_even_numbers_in_array(int* b, int n);
//нахождение кол-ва нечёт 
int nechet(int n1, int** a);
//нахождение кол-ва чёт 
int chet(int n2, int** a);
//нахождение кол-ва чёт и создание строк 
void chet_mas(int n1, int n2, int** a);
int main()
{
    setlocale(LC_ALL, "Russian");
    int n1, n2; // n- столбцы, m -строки 
    cout << "Введите размерность массива m х n: \n";
    cin >> n1 >> n2;
    int y1;
    cout << "Введите нижний предел для генерации случайных чисел: \n";
    cin >> y1;
    int y2;
    cout << "Введите верхний предел для генерации случайных чисел: \n";
    cin >> y2;
    int** x;
    x = create_array(n1, n2, y1, y2);
    cout << "\n Исходный массив: \n";
    print_array(n1, n2, x);
    int* l;
    int* h;
    l = (int*)malloc(n1 * sizeof(int));
    h = (int*)malloc(n2 * sizeof(int));
    int k, ch;
    k = nechet(n1, x);
    ch = chet(n2, x);
    chet_mas(n1, n2, x);
    if (k < n2)
    {
        n1 = n1 + ch - 1;
        n2 = n2 - k;
        l = (int*)realloc(l, (int)n1);
        h = (int*)realloc(h, (int)n2);
        cout << "\n Результирующий массив: \n";
        print_array(n1, n2, x);
    }
    else cout << "\n Обработать невозможно \n";
    system("pause");
    return 0;
}
//Реализация функций 
//Создание динамического массива размера n и заполнение его случайными числами вдиапазоне [a,b] 
int** create_array(int n1, int n2, int y3, int y4)
{
    int** a;
    a = new int* [n1];
    srand(time(0));
    for (int i = 0; i < n1; i++)
    {
        a[i] = new int[n2];
        for (int j = 0; j < n2; j++)
            a[i][j] = y3 + rand() % (y4 - y3 + 1);
    }
    return a;
}
//Вывод на экран динамического массива b размера n 
void print_array(int n1, int n2, int** a)
{
    for (int i = 0; i < n1; i++)
    {
        for (int j = 0; j < n2; j++)
            cout << a[i][j] << "\t";
        cout << endl;
    }
}
//нахождение кол-ва нечёт 
int nechet(int n1, int** a)
{
    int k = 0;
    for (int i = 0; i < n1; i++)
        if (a[i][0] % 2 != 0) k++;
    return k;
}
//нахождение кол-ва чёт 
int chet(int n2, int** a)
{
    int ch = 0;
    for (int i = 0; i <= n2; i++)
        if (a[0][i] % 2 == 0)
            ch++;
    return ch;
}
//нахождение кол-ва чёт и создание строк 
void chet_mas(int n1, int n2, int** a)
{
    int f = 0;
    for (int i = 0; i < n2; i++)
        if (a[0][i] % 2 == 0)
        {
            for (int j = 0; j < n2; j++)
                a[n1 + f][j] = a[0][i];
            f++;
        }
}

И появляется следующая ошибка:

Подскажите, что следует мне поправить? Благодарю за любую помощь.

Answer 1

В вашем коде содержится явный доступ за пределы массива. В первом варианте это

x[n1 + ch][j]

в main, а во втором варианте это

a[n1 + f][j]

в chat_mas. Кто вам разрешил обращаться по индексу n1 + что-то, когда массив имеет размер [n1]?

Ваш первый вариант в результате такого доступа не падает потому, что массив x объявлен с размером [100][100], то есть "с запасом", если величина n1 существенно меньше 100. Но если величина n1 приблизится к 100, то вылетать за пределы массива и падать начнет и ваш первый вариант.

Во втором варианте вы создаете массив точного размера [n1][n2]. Этот вариант, разумеется, будет вылетать за пределы массива и падать всегда. Что вы и наблюдаете.

READ ALSO
Создать класс по обработке массива данных

Создать класс по обработке массива данных

ООП в плюсах для меня тема новаяНужно написать класс my_sample который должен иметь среди своих приватных полей вектор long double, который назвать...

116
Спецификатор времени компиляции noexcept

Спецификатор времени компиляции noexcept

А для чего нужны спецификации исключения noexcept(true) и noexcept(false), как и когда они используются?

107
Диалог vuetify vue js и jquery

Диалог vuetify vue js и jquery

Я пытаюсь сделать диалог vuetify(библиотека vue js) растягиваемым с помощью resize jqueryЯ столкнулся с рядом проблем: 1) jquery расширяет диалог по всем...

131