Исключение: нарушение прав на чтение. ** dynamicArray ** был 0x1118235. произошло - PullRequest
0 голосов
/ 31 октября 2018
#include "pch.h"
#include <iostream>
#include <string>
using namespace std;
int **dynamicArray ;
int ROWS, COLUMNS;

//---------------------------------
int input_matrix(int ROWS, int COLUMNS)
{

    //---------------------------------------
    //memory allocated for elements of rows.
    int **dynamicArray = new int *[ROWS];

    //memory allocated for  elements of each column.
    for (int i = 0; i < ROWS; i++)
        dynamicArray[i] = new int [COLUMNS];

    //free the allocated memory
    for (int i = 0; i < ROWS; i++)
        delete[] dynamicArray[i];
    delete[] dynamicArray;
    //-------------------------------------

    for (int i = 0; i < ROWS; i++)
    {
        for (int j = 0; j < COLUMNS; j++)
        {
            cin >> dynamicArray[i][j];
        }
    }
    return 0;
}
//---------------------------------------------
int print_matrix(int **Array)
{
    for (int k = 0; k < ROWS; k++)
    {
        for (int m = 0; m < COLUMNS; m++)
        {
            cout << Array[k][m];
            if (m == COLUMNS)
            {
                cout << "\n";
            }
        }
    }

    return 0;

}

//---------------------------------
int main()
{
    cin >> ROWS;
    cin >> COLUMNS;
    input_matrix(ROWS, COLUMNS);
    print_matrix(dynamicArray);

}

Этот код определяет матрицу, получает входные данные и помещает их в члены матрицы, но каждый раз, когда я запускаю этот код, я получаю сообщение об ошибке нарушения прав чтения в строке:

cin >> dynamicArray[i][j];

вот полная информация: Исключение: нарушение прав на чтение. dynamicArray было 0x1118235. произошло

Что мне делать?

Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 31 октября 2018

Есть несколько проблем с вашей программой. Позвольте мне перечислить их всех по одному.

  1. Как уже упоминалось в одном из комментариев, вы сразу освобождение памяти сразу после того, как вы ее распределили. Определенно это приведет к ошибке сегментации или нарушению доступа к памяти, когда Вы получаете доступ к освобожденной памяти.
  2. Когда вы выделяете память, вы не назначение выделенных указателей памяти глобальному указателю dynamicArray вместо этого вы создаете локальную переменную с то же имя внутри функции input_matrix. Как этот указатель переменная область видимости заканчивается внутри функции, которую вы теряете память выделены. Следовательно, вы снова столкнетесь с ошибкой сегментации или памятью нарушение доступа внутри print_matrix функции.
  3. Внутри print_matrix функция во внутреннем цикле for, который вы проверяете, если m==COLUMNS печатает новую строку, этого никогда не произойдет, так как m всегда меньше COLUMNS.
  4. Наконец, как показывает предыдущий ответ, когда вы используете C ++, лучше использовать вектор с умными указателями, чем использовать массивы и необработанные указатели для лучшего управления памятью.

Следующий фрагмент разрешает эти проблемы.

#include <iostream>
#include <string>
using namespace std;
int **dynamicArray ;
int ROWS, COLUMNS;

//---------------------------------
int input_matrix(int ROWS, int COLUMNS)
{
    //---------------------------------------
    //memory allocated for elements of rows.
    dynamicArray = new int *[ROWS];

    //memory allocated for  elements of each column.
    for (int i = 0; i < ROWS; i++)
        dynamicArray[i] = new int [COLUMNS];

//    cout<<"Input array values\n";

    for (int i = 0; i < ROWS; i++)
    {
        for (int j = 0; j < COLUMNS; j++)
        {
            cin>>dynamicArray[i][j];
        }
    }
    return 0;
}

void free_matrix_memory()
{
    cout<<"freeing allocated memory\n";
    //free the allocated memory
    for (int i = 0; i < ROWS; i++)
        delete[] dynamicArray[i];
    delete[] dynamicArray;
    //-------------------------------------
}

//---------------------------------------------
int print_matrix(int **Array)
{
    cout<<"printing matrix\n";
    for (int k = 0; k < ROWS; k++)
    {
        for (int m = 0; m < COLUMNS; m++)
            cout << Array[k][m];
        cout << "\n";
    }
    return 0;
}

//---------------------------------
int main()
{
    cout<<"Row and column values\n";
    cin>> ROWS;
    cin>> COLUMNS;
    input_matrix(ROWS, COLUMNS);
    print_matrix(dynamicArray);
    free_matrix_memory();
}

Тем не менее, для вас может быть сделано много улучшений, таких как избегание глобальных переменных и т. Д. Я оставляю за вами выполнение этих улучшений.

0 голосов
/ 01 ноября 2018

Если вы запустите программу под Valgrind, она точно скажет вам, что не так:

==6939== Invalid read of size 8
==6939==    at 0x1092C9: input_matrix(int, int) (53083248.cpp:30)
==6939==    by 0x1093FA: main (53083248.cpp:59)
==6939==  Address 0x4d7ecc0 is 0 bytes inside a block of size 16 free'd
==6939==    at 0x48373EB: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6939==    by 0x109296: input_matrix(int, int) (53083248.cpp:23)
==6939==    by 0x1093FA: main (53083248.cpp:59)
==6939==  Block was alloc'd at
==6939==    at 0x483654F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6939==    by 0x1091D3: input_matrix(int, int) (53083248.cpp:14)
==6939==    by 0x1093FA: main (53083248.cpp:59)
==6939== 
==6939== Invalid write of size 4
==6939==    at 0x496FFF0: std::istream::operator>>(int&) (istream.tcc:194)
==6939==    by 0x1092EA: input_matrix(int, int) (53083248.cpp:30)
==6939==    by 0x1093FA: main (53083248.cpp:59)
==6939==  Address 0x4d7ed10 is 0 bytes inside a block of size 8 free'd
==6939==    at 0x48373EB: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6939==    by 0x10927D: input_matrix(int, int) (53083248.cpp:22)
==6939==    by 0x1093FA: main (53083248.cpp:59)
==6939==  Block was alloc'd at
==6939==    at 0x483654F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6939==    by 0x10922A: input_matrix(int, int) (53083248.cpp:18)
==6939==    by 0x1093FA: main (53083248.cpp:59)
==6939== 
==6939== Invalid read of size 8
==6939==    at 0x10934D: print_matrix(int**) (53083248.cpp:42)
==6939==    by 0x10940C: main (53083248.cpp:60)
==6939==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==6939== 
==6939== 
==6939== Process terminating with default action of signal 11 (SIGSEGV)
==6939==  Access not within mapped region at address 0x0
==6939==    at 0x10934D: print_matrix(int**) (53083248.cpp:42)
==6939==    by 0x10940C: main (53083248.cpp:60)

Существует и чтение и запись в память, которая была освобождена, и разыменование dynamicArray, которое никогда не назначалось.

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

Я советую вам избегать необработанных new[] и delete[] - предпочитайте использовать контейнеры и умные указатели, которые владеют ресурсами для вас, и автоматически освобождать их от своих деструкторов.

0 голосов
/ 31 октября 2018

В этом случае нет оснований для ручного управления вашей памятью. Вместо этого используйте std::vector (который является динамическим массивом) или даже фактическую библиотеку Matrix, например 'Eigen'.

...