#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. произошел
Что я должен делать?
Заранее спасибо.
Вы должны освободить память dynamicArray
в main
, когда закончите с ней.
У вас есть множество других мелких проблем: Почему бы не использовать vector
? Не используйте глобальные переменные. using namespace std
считается плохим. В print_matrix
m
никогда не будет равняться COLUMNS
.
Единственная причина, по которой я могу придумать, почему ошибка не очевидна для вас, состоит в том, что вы не понимаете, что делает «освобождение памяти» - у вас даже есть комментарий в вашем коде, говорящий «освободите выделенную память». Да, вы заполнили матрицу, но это не значит, что «теперь мне больше не нужна память, поскольку матрица заполнена и теперь хранит мои значения». Если я ошибаюсь, пусть будет так, но, опять же, это единственная правдоподобная причина, по которой вы могли бы поверить, что освобождение памяти перед фактическим использованием матрицы сработает.
В этом случае нет причин вручную менять управление памятью. Вместо этого используйте std::vector
(динамический массив) или даже настоящую библиотеку Matrix, например Eigen.
Это должен быть комментарий, а не ответ.
Думаю, это идеальный ответ. OP даже спрашивает: «Что мне делать?»
Тем не менее, предложение, поскольку мы не знаем, разрешено ли ему использовать std::vector
или сторонние библиотеки.
Да, так как вопрос был помечен как C++.
Всем большое спасибо за ваши ответы на этот вопрос. Я не знаю, как использовать вектор вместо этого (также я вообще не знаю, что это за вектор :))
Это не дает ответа на вопрос. Чтобы критиковать или запрашивать разъяснения у автора, оставьте комментарий под его сообщением. - Из обзора
@TobySpeight Он отвечает на вопрос ОП - с таким же уровнем детализации, как ОП задал свой вопрос. SO - это не служба кодирования или обучения - я даю полный ответ, который, если он используется, решит проблему OP на 100%. Он даже широко спрашивает: «Что мне делать?» Пожалуйста, опишите подробнее, почему вы думаете, что это не отвечает на вопрос OP?
Я уверен, что это хороший совет, но он кратковременен для объяснения того, что было не так. (На самом деле, вопрос лучше многих - он действительно компилируется, если вы удаляете локальное включение. По общему признанию, он просто блокирует ожидание ввода, но у вас не может быть всего!). Мне это больше похоже на хороший комментарий, чем на ответ.
С вашей программой есть несколько проблем. Позвольте мне перечислить их все по порядку.
dynamicArray
вместо этого вы создаете локальную переменную с
то же имя внутри функции input_matrix
. Поскольку этот указатель
область видимости переменной заканчивается внутри функции, вы теряете память
выделено. Следовательно, вы снова столкнетесь с ошибкой сегментации или памятью.
нарушение доступа внутри функции print_matrix
.print_matrix
во внутреннем цикле for вы проверяете, печатает ли m==COLUMNS
новую строку, этого никогда не произойдет, поскольку m всегда меньше COLUMNS
.Следующий фрагмент решает эти проблемы.
#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();
}
Тем не менее, многие улучшения могут быть сделаны для вас, например, избегать глобальных переменных и т. д., Я оставляю вам делать эти улучшения.
Большое спасибо, вы молодцы.
Если вы запустите программу под 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[]
- предпочитайте использовать контейнеры и интеллектуальные указатели, которые владеют ресурсами для вас и автоматически освобождают их от своих деструкторов.
Вы выделяете, а затем немедленно освобождаете массив в
input_matrix
. После того, как вы освободили массив, вы не должны его трогать / использовать. Но затем в конце этой функции вы использовать массив, который был освобожден.