I get a segmentation fault when I run the code below.
int main()
{
int R, C, val;
cin>>R>>C;
vector<vector<int>> a;
for(int i = 0; i < R; i++)
{
for(int j = 0; j < C; j++)
{
cin>>val;
a[i].push_back(val);
}
}
But when I change it to this, it seems to work. What is the reason?
int main()
{
int R, C, val;
cin>>R>>C;
vector<vector<int>> a;
for(int i = 0; i < R; i++)
{
vector<int>temp;
for(int j = 0; j < C; j++)
{
cin>>val;
temp.push_back(val);
}
a.push_back(temp);
}
I get the same fault no matter what the value of R and C is kept.
You have never told what is the size of vector<vector<int>>, and you try to access a[i].
You have to resize the vector.
int main()
{
int R, C;
std::cin >> R >> C;
std::vector<std::vector<int>> a(R, std::vector<int>(C));
for(int i = 0; i < R; i++)
{
for(int j = 0; j < C; j++)
{
std::cin >> a[i][j]; //because we resize the vector, we can do this
}
}
}
Related
This is the question I am trying to code. I have written the following code but I don't know how can I store the elements in the vector in getComponent() function and retrieve it inside main function.
I have used ans as a vector variable. I am passing its address so that I do not have to return anything. But I am getting compilation error while running the code.
#include<vector>
#include <bits/stdc++.h>
using namespace std;
void getComponent(int **edges, int n, int sv, int * visited, vector<int>*ans){
visited[sv] = 1;
ans->push_back(sv);
for(int i = 0; i < n; i++){
if(i == sv)continue;
if(edges[sv][i] == 1){
if(visited[i] == 0)
getComponent(edges, n, i, visited, ans);
}
}
}
int main() {
// Write your code here
int n, e;
cin>>n>>e;
int **edges = new int *[n];
for(int i = 0; i < n; i++){
edges[i] = new int[n];
for(int j = 0; j < n; j++){
edges[i][j] = 0;
}
}
for(int i = 0; i <e; i++){
int a, b;
cin>>a>>b;
edges[a][b] = 1;
edges[b][a] = 1;
}
int *visited = new int[n];
for(int i = 0; i < n; i++)
visited[i] = 0;
for(int i = 0; i < n; i++){
if(visited[i] == 0){
vector<int>*ans;
getComponent(edges, n, i, visited, ans);
for (auto x : ans)
cout << x << " ";
cout<<endl;
}
}
}
You need to actually create an ans vector and pass it's address:
for(int i = 0; i < n; i++){
if(visited[i] == 0){
vector<int> ans;
getComponent(edges, n, i, visited, &ans);
for (auto x : ans)
cout << x << " ";
cout<<endl;
}
}
After that you should replace all C-style arrays with std::vector and pass references instead of pointers.
this is my code i wanted to return a 2d array from a function and use it in other function inorder to modify it.
#include<bits/stdc++.h>
using namespace std;
int** createMat(int row,int col){
int arr[row][col];
for(int i=1;i<=row;i++){
for(int j=1;j<=col;j++){
cin>>arr[i][j];
}
}
return arr;
}
int main(){
int row,col;
cin>>row;
cin>>col;
createMat(row,col);
}
You should use containers. They are the bread and butter of C++.
Please follow the advice of Some programmer dude. Invest in a good C++ book.
#include <vector>
#include <iostream>
std::vector<std::vector<int>> createMat(int row, int col)
{
std::vector<std::vector<int>> data;
data.resize(row);
for (auto& c : data)
{
c.resize(col);
}
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
std::cin >> data[i][j];
}
}
return data;
}
int main() {
int row, col;
std::cin >> row;
std::cin >> col;
auto mydata = createMat(row, col);
// do something with it
}
Or if you don't want to use vector, you can use pointer and do it like this.
#include<iostream>
int** createMat(int row,int col)
{
int **arr = 0;
arr = new int*[row];
for (int r = 0; r < row; r++)
{
arr[r] = new int[col];
for (int c = 0; c < col; c++)
{
std::cin>>arr[r][c];
}
}
return arr;
}
int main()
{
int row,col;
std::cin>>row;
std::cin>>col;
int** createdMat = createMat(row,col);
std::cout << "print Array\n";
for (int r = 0; r < row; r++)
{
for (int c = 0; c < col; c++)
{
printf("%i ", createdMat[r][c]);
}
printf("\n");
}
//free memory
for (int r = 0; r < row; r++)
{
delete [] createdMat[r];
}
delete [] createdMat;
}
I was making a cpp program in which it takes two input from the user which determine the size of the 2d array and pass the values to the mat class constructor and dynamically create an array of the user's defined size. But, I don't know why it is not working and showing segmentation fault
#include<iostream>
using namespace std;
class mat{
int **a;
int r, c;
public:
mat(int row, int col){
r = row;
c = col;
for(int i = 0; i < r; i++){
*a = new int[r];
*a++;
}
}
void input(){
for(int i = 0; i < r; i++){
for(int j = 0; i < c; j++){
cin >> a[i][j];
}
}
}
void display(){
for(int i = 0; i < r; i++){
for(int j = 0; i < c; j++){
cout << a[i][j] << "\t";
}
cout << endl;
}
}
};
int main()
{
int r, c;
cout << "enter row :";
cin >> r;
cout << "enter column :";
cin >> c;
mat m(r, c);
m.input();
cout << "array \n";
m.display();
}
I can feel that the issue is with the for loop in the constructor or maybe I am doing it wrong.
The class contains several errors.
The variable a is never initialized. When we try to address the memory pointed to by a we get a segmentation fault. We can initialize it like this a = new int*[r]
We should not change where a point's to, so don't use a++. Otherwise a[i][j] will not refer to the i'th row and the j'th column. We would also want to release the memory at some point.
The inner loop for the columns for(int j = 0; i < c; j++) once entered will never terminate and will eventually produce a segmentation fault. We need to change i < c to j < c.
If we fix these errors, it looks like this:
class mat {
int** a;
int r, c;
public:
mat(int row, int col) {
r = row;
c = col;
a = new int*[r];
for (int i = 0; i < r; i++) {
a[i] = new int[c];
}
}
void input() {
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
cin >> a[i][j];
}
}
}
void display() {
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
cout << a[i][j] << "\t";
}
cout << endl;
}
}
};
I am working on a 2D vector of doubles matrix solver and my matrices keep turning out incorrectly.
The intended matrix output at "Level 3" is {(top, left to right)3,4 over (bottom, left to right)1,2} but my code keeps outputting {2,1 over 3,4}. I keep trying to invert the values but whenever I do so I keep getting an out of bounds exception.
vector<double> gauss(mat B) {
int n = B.A.size();
for (int i=0; i<n-1; i++) {
// Search for maximum in this column
double maxEl = abs(B.getSlot(i,i));
int maxRow = i;
for (int k=i+1; k<n; k++) {
if (abs(B.getSlot(k,i)) > maxEl) {
maxEl = abs(B.getSlot(k,i));
maxRow = k;
}
}
// Swap maximum row with current row
for (int k=i; k<n+1;k++) {
double tmp = B.getSlot(k,maxRow);
B.editSlot(k,maxRow,B.getSlot(k,i));
B.editSlot(k,i,tmp);
}
cout << "\n\nlevel 3: \n";
B.display();
}
B.display();
// Solve equation Ax=b for an upper triangular matrix A
vector<double> x(n);
for (int i=n-1; i>=0; i--) {
x[i] = B.getSlot(i,n)/B.getSlot(i,i);
for (int k=i-1;k>=0; k--) {
B.editSlot(k,n,B.getSlot(k,n)-B.getSlot(k,i)*x[i]);
}
}
return x;
}
int main() {
int n = *Size of array is properly retrieved*
mat my_mat(n,n);
// Read input data
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
double myDub;
inFile >> myDub;
my_mat.editSlot(i,j,myDub);
}
}
// Calculate solution
vector<double> x(n);
x = gauss(my_mat);
}
And my class code is as follows
class mat
{
public:
mat(int x,int y){
int row = x;
int col = y;
n=row;
A = vector<vector<double>>(row,vector<double>(row,0));
for(int i=0; i<row; i++)
{
for(int j=0; j<col; j++)
{
cout<<setw(6)<<A[i][j];
}
cout<<endl;
}
}
void editSlot(int x, int y, double val){A[y][x] = val;}
double getSlot(int x, int y){return A[y][x];}
void display()
{
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
cout<<setw(6)<<A[j][i];
}
cout<<endl;
}
cout<<endl;
}
vector<vector<double>> A;
private:
int n;
};
Try to change your input loop:
// Read input data
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
double myDub;
inFile >> myDub;
my_mat.editSlot(j, i, myDub); // < - j, i swapped.
}
}
Can you provide sample input that you use and what output you expect?
How can I combine these two functions to create a program that will allow a user to enter the count of vertices and then enter the graph edges?
#include <iostream>
using namespace std;
int **malloc2d(int r, int c)
{
int **t = new int*[r];
for(int i = 0; i < r; i++)
t[i] = new int[c];
return t;
}
int main()
{
int i;
int j;
int adj[V][V];
for(i = 0; i < V; i++)
for(j = 0 ; j < V; j++)
adj[i][j] = 0;
for(i = 0; i < V; i++)
adj[i][i]= 1;
while (cin>> i >> j)
{
adj[i][j] = 1;
adj[j][i] = 1;
}
system("pause");
return 0;
}
You could use std::vector<std::vector<bool>> or boost::adjacency_matrix, it's simpler.
std::size_t v;
std::cin >> v;
std::vector<std::vector<bool>> g(v);
for(auto& elem: g)
elem.resize(v, false);
boost::adjacency_matrix<boost::undirectedS> ug(v);
std::size_t e;
std::cin >> e;
for(std::size_t i = 0; i < e; ++i)
{
std::size_t v1, v2;
std::cin >> v1 >> v2;
g.at(v1).at(v2) = true;
g.at(v2).at(v1) = true;
boost::add_edge(v1, v2, ug);
}