#c #segmentation-fault #vertices
#c #ошибка сегментации #вершины
Вопрос:
Создаются два вектора, и обоим векторам присваиваются значения, а затем два вектора умножаются друг на друга. (Матричное умножение). Выдает ошибку ошибки сегментации в функции умножения. Это что-то связанное с попыткой получить доступ к местоположению вне области видимости?
#include<iostream>
#include <vector>
using namespace std;
int n;
vector <int> mat1Rows;
vector <int> mat2Rows;
vector <int> multRows;
vector <vector<int> > mat1;
vector <vector<int> > mat2;
vector <vector<int> > multMat;
void assignValues(int num){
for(int i = 0; i < num; i ){
for(int j = 0; j < num; j ){
mat1Rows.push_back(j);
mat2Rows.push_back(j);
}
mat1.push_back(mat1Rows);
mat2.push_back(mat2Rows);
mat1Rows.clear();
mat2Rows.clear();
}
}
void multiply(int n){
for(int i = 0; i < n; i){
for(int j = 0; j < n; j){
for(int k = 0; k < n; k){
multMat[i][j] = mat1[i][k] * mat2[k][j];
}
}
}
}
void displayMult(int n){
for(int i = 0; i < n; i ){
for(int j = 0; j < n; j ){
cout << multMat[i][j] << " " ;
}
cout << endl;
}
}
int main(){
cout << "Enter the size of the matrix: ";
cin >> n;
assignValues(n);
multiply(n);
displayMult(n);
return 0;
}
Комментарии:
1. Ваша программа не компилируется. Пожалуйста, добавьте обязательные включения.
2. «Это что-то с попыткой получить доступ к местоположению вне области видимости?» — это в значительной степени то, что означает ошибка сегментации. Самый простой способ найти это — пошагово выполнить вашу программу построчно с помощью debugger.
3. @NO_NAME Добавил includes .
4.
multMat
вектор пуст в тот момент, когда вы пытаетесь получить ссылку на его элемент сmultMat[i][j]
помощью .5. @Rashmika97 Используйте
vector::at()
вместо[ ]
для доступа к элементам в векторе. Затем вы увидите, что программа будет выдаватьstd::out_of_range
исключение вместо просто ошибки seg, когда она встречаетat()
вызов, который выходит за рамки.
Ответ №1:
multMat[i][j] = mat1[i][k] * mat2[k][j];
Внутри нет памяти multMat
, так как вы не зарезервировали никакой памяти для элементов. Вам нужно указать vector для выделения памяти. Вы можете сделать это с помощью resize, чтобы выделить память для элементов и изменить размер вектора..
void multiply(int n) {
multMat.resize(n);
for (autoamp;amp; i : multMat) {
i.resize(n);
}
... rest of the code ...
}
Проверка std::vector::operator[]
границ не выполняется. Поэтому, если вы укажете индекс за пределами допустимых границ и попытаетесь присвоить что-то возвращаемой ссылке, произойдет неопределенное поведение. Используйте std::vector::at()
, чтобы всегда быть уверенным, что ваши индексы действительны.
Комментарии:
1. Кстати,
reserve()
размер вектора не изменяется.2. Разве это не должно быть
resize()
вместоreserve()
?reserve()
предотвратил бы ошибку сегментации, но доступ к полям за пределамиsize()
вектора по-прежнему пахнет для меня неопределенным поведением.3. Было бы целесообразно зарезервировать память, поскольку это динамическое распределение?
4. Он
operator[]
не выполняет никакого распределения. Он не выполняет никакой проверки. Использование его за пределами границ является неопределенным поведением.5. Да, я согласен, что в случае вектора какого-то фундаментального типа это не имеет большого значения. Однако лучше знать, когда использовать
resize()
и когдаreserve()
. Это может вызвать довольно странную ошибку в векторе объектов с конструктором и деструктором. Кроме того, попытка использованияpush_back
переопределила бы данные, еслиresize()
resize()
бы был вызван только if only .