Ошибка с выделением памяти

245
18 декабря 2017, 14:38

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

Смысл такой, что в программе нужно использовать функции и избавиться от глобальных переменных. В целом всё хорошо и с задачей я справился, но осталась одна переменная которая задаёт размер матрицы. От неё я тоже хочу избавиться и делаю функцию takeSize() со статичной переменной которая запоминает введённый в другой функции размер. В итоге получается что когда я пихаю возвращаемое этой функцией значение в квадратные скобки, в месте инициализации массива(кусок ниже с меткой Листинг 1), я получаю на выхлопе в этой строке ошибку, которая гласит, что чтение памяти невозможно. Так же из сообщений об ошибке было видно, что программа пыталась выделить все имеющиеся 4 ГБ.

//Листинг 1
int **matrix = new int*[takeSize()];
            for (int count = 0; count < takeSize(); count++)
            {
                matrix[count] = new int[takeSize()];
            }

Вопрос 1: Как сделать так, чтобы оно заработало без глобальной переменной, которая описывает размер массива. Вопрос 2: Почему происходят такие интересные вещи с памятью(выделение всех 4ГБ(Был указан размер в байтах и методом деления данного на 2^10 на выхлопе получилось 4095МБ)

P.S. Будет очень даже шикарно, если будут ответы на оба вопроса, но если будет ответ на 1-ый вопрос, то уже хорошо Код:

            // PR5_din_arrays.cpp: определяет точку входа для консольного приложения.
            //
            /*Дана целочисленная квадратная матрица. Определить:
            1) Сумму элементов в тех строках, которые не содержат отрицательных элементов
            2) минимум среди сумм элементов диагоналей, параллельных главной диагонали матрицы.
            */
            #include "stdafx.h"
            #include <time.h>
            #include <iomanip>
            #include <iostream>
            using namespace std;
            int SetSize()//задаёт размер массива. Так как матрица квадратная, будем оперировать 1 числом.
            {
                int size = 2;
                cout << "input the size of matrix" << endl;
                cin >> size;
                while (size < 2)
                {
                    cout << "incorrect value!" << endl;
                    cout << "input the size of matrix" << endl;
                    cin >> size;
                }
                return size;
            }
            void MakeArray(int** a, int size)
            {
                srand(time(NULL));
                cout << "Original array:" << endl;
                for (int i = 0; i < size; i++)
                {
                    for (int j = 0; j < size; j++)
                    {
                        a[i][j] = rand() % 101 - 50;
                        cout << setw(6) << left << a[i][j]; 
                    }
                    cout << endl;
                }
            }
            void ClearArrays(int *array, int size, int *array2)
            {
                int ds = size - 1;
                for (int i = 0; i < size; i++)
                {
                    array[i] = 0;
                }
                for (int i = 0; i < ds; i++)
                {
                    array2[i] = 0;
                }
            }
            int MakeSum(int **a, int size)
            {
                int sv = 0;
                for (int i = 0; i < size; i++)
                {
                    for (int j = 0; j < size; j++)
                    {
                        if (a[i][j] < 0)
                        {
                            sv = 0;
                            break;
                        }
                        else
                        {
                            sv = sv + a[i][j];
                        }
                    }
                }
                return sv;
            }
            int MakeMult(int *diasum, int **matrix, int N)
            {
                int ds = N - 1;
                int min_val1 = INT_MAX;
                int min_val = INT_MAX;
                for (int i = 1; i < N; i++)
                {
                    int x = i;
                    int y = 0;
                    while ((x <= N - 1) && (y <= N - 1))
                    {
                        diasum[i - 1] = diasum[i - 1] + matrix[y][x];
                        x++;
                        y++;
                    }
                    for (int i = 0; i < ds; i++)
                    {
                        if (diasum[i] < min_val)
                        {
                            min_val = diasum[i];
                        }
                    }
                }
                for (int i = 1; i < N; i++)
                {
                    int y = i;
                    int x = 0;
                    while ((y <= N - 1) && (x <= N - 1))
                    {
                        diasum[i - 1] = diasum[i - 1] + matrix[y][x];
                        x++;
                        y++;
                    }
                    for (int i = 0; i < ds; i++)
                    {
                        if (diasum[i] < min_val1)
                        {
                            min_val1 = diasum[i];
                        }
                    }
                }
                if (min_val1 == INT_MAX)
                {
                    min_val1 = 0;
                }
                if (min_val == INT_MAX)
                {
                    min_val = 0;
                }
                if (min_val1 < min_val)
                {
                    min_val = min_val1;
                }
                return min_val;
            }
            void WriteRess(int *sum, int size, int min_val)
            {
                cout << endl << endl;
                cout << "Minimal element from diagonals " << min_val;
                cout << endl;
                cout << "sum-s of rows: " << endl;
                for (int i = 0; i < size; i++) 
                {
                    if (sum[i] != 0)
                    {
                        cout << setw(6) << left << sum[i];
                    }
                    else
                    {
                        cout << i + 1 << " Row have elements < 0 " << endl;
                    }
                }
            }
            int takeSize(int a = 0)
            {
                static int size;
                size = 0;
                size = size + a;
                return size;
            }
            int _tmain(int argc, _TCHAR* argv[])
            {
                //int N = SetSize();
                takeSize(SetSize());
                int **matrix = new int*[takeSize()];
                for (int count = 0; count < takeSize(); count++)
                {
                    matrix[count] = new int[takeSize()];
                }
                /*выше объявляю саму матрицу*/
                int *sum = new int[takeSize()]; // в этот массив пишутся суммы строк. Должен быть динамическим ибо мы не знаем какого порядка будет матрица
                int *diasum = new int[takeSize() - 1]; // массив в который будут попадать суммы диагоналей
                ClearArrays(sum, takeSize(), diasum);
                MakeArray(matrix, takeSize());
                for (int i = 0; i < takeSize(); i++)
                {
                    sum[i] = MakeSum(matrix, takeSize());
                }
                cout << endl;
                WriteRess(sum, takeSize(), MakeMult(diasum, matrix, takeSize()));
                cout << endl;
                system("pause"); 
                return 0;
            }
Answer 1
        int takeSize(int a = 0)
        {
            static int size;
            size = 0;
            size = size + a;
            return size;
        }

Итак, вы при любом вызове функции ОБНУЛЯЕТЕ size, прибавляете к нему a и возвращаете полученное значение - то есть a...

Если уж вы не верите в то, что статическая переменная будет занулена, как и глобальная - то инициализируйте ее нулем, а не переприсваивайте:

        int takeSize(int a = 0)
        {
            static int size = 0;
            size = size + a;
            return size;
        }

Ну, а здесь

int *diasum = new int[takeSize() - 1];

вы, понятно, пытаетесь выделить -1 байт. Каковое значение при преобразовании в беззнаковое превращается в максимально возможное для беззнакового типа.

Кстати, вообще-то я бы на вашем месте использовал не int - ведь все равно не будет отрицательного количества памяти! - а стандартный size_t.

READ ALSO
Qsort не работает в XCode

Qsort не работает в XCode

Столкнулся с проблемой при решении задачи на XCode

204
Реализация алгоритма COS(дискретное логарифмирование) [требует правки]

Реализация алгоритма COS(дискретное логарифмирование) [требует правки]

Ребят, помогите, пожалуйста с реализацией алгоритма cosалгоритм cos Описанный там алгоритм, не могу понять, может сможете объяснить на понятном...

161