Dyanamic 2d array in C++ using double pointer - c++

I have the following code, I made sure I did everything as explained in Pointer-to-pointer dynamic two-dimensional array
I need my 2d matrix to be dyanmic i.e the user needs to enter the dimensions. But I am getting error in my cin when taking the input form the user. whats wrong with the following code?
int numberOfRows, numberOfColumn;
cout << "Please enter the number of rows: ";
cin >> numberOfRows;
cout << endl << "Please enter the number of columns ";
cin >> numberOfColumn;
int** matrix= new int*[numberOfRows];
for (int i=0; i<numberOfRows; i++)
{
matrix[numberOfRows]= new int[numberOfColumn];
}
for (int i=0; i<numberOfRows; i++)
{
for(int j=0; j<numberOfColumn; j++)
{
cout << "Please enter Row " << (i+1) << " Column "<< (j+1) <<" element: ";
cin>> matrix[i][j];
cout << endl;
}
}
for (int i=0; i<numberOfRows; i++)
{
for(int j=0; j<numberOfColumn; j++)
{
cout << matrix[i][j];
}
}

You have this:
for (int i=0; i<numberOfRows; i++)
{
matrix[numberOfRows]= new int[numberOfColumn];
}
Should be:
for (int i=0; i<numberOfRows; i++)
{
matrix[i]= new int[numberOfColumn];
}
Notice that the matrix[numberOfRows] changed to matrix[i]

While allocating memory in for loop
matrix[i]= new int[numberOfColumn];
instead of matrix[numberOfRows]= new int[numberOfColumn];
Note:you also need to free the allocated memory
corrected code
http://ideone.com/ILw1qa

Related

Why am I getting a "vector out of range" error?

When I try to run my code, it compiles fine, but during runtime it gives an out of range vector error. Can anyone help me out?
I have written my code in Xcode:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int numOfRows = 0;
cout << "Enter number of rows: ";
cin >> numOfRows;
vector<vector<int>> vec;
int sizeOfAnotherArray = 0;
int value = 0;
for (int i = 0; i < numOfRows; i++) {
cout << "Enter size of another array: ";
cin >> sizeOfAnotherArray;
vec.resize(numOfRows,vector<int>(sizeOfAnotherArray));
for (int j = 0; j < sizeOfAnotherArray; j++) {
cout << "Store Value: ";
cin >> value;
vec.at(i).at(j) = value;
}
}
for (int i = 0; i < numOfRows; i++) {
for (int j = 0; j < sizeOfAnotherArray; j++) {
cout << vec.at(i).at(j) << " ";
}
cout << "\n";
}
return 0;
}
The odd thing about your code is that you enter sizeOfAnotherArray multiple times and therefore resize your whole array multiple times. But note that you only change the number of rows. Each row you add will have the latest size but earlier rows will keep the size they originally had.
This means that if one of the later values for sizeOfAnotherArray is larger than one of the earlier values then you are going to get an out of range error, because the earlier row will still have the smaller size.
I'm guessing that the code you meant to write is this. It creates a ragged array, which is an array where the number of columns varies depending on which row you are on.
cout << "Enter number of rows: ";
cin >> numOfRows;
vector<vector<int>> vec(numRows); // create array with N rows
for (int i = 0; i < numOfRows; i++) {
cout << "Enter size of another array: ";
cin >> sizeOfAnotherArray;
vec.at(i).resize(sizeOfAnotherArray); // resize this row only
for (int j = 0; j < sizeOfAnotherArray; j++) {
...
}
for (int i = 0; i < vec.size(); i++) {
for (int j = 0; j < vec.at(i).size(); j++) { // loop on the size of this row
cout << vec.at(i).at(j) << " ";
}
cout << "\n";
}

2D integer array in c++ with uneven number of elements in each row

The number of rows and columns of this array are given by the user however the number of rows are not the same (the array is uneven) and also the user will fill the array by entering the elements.
This is the code that I wrote but when I try to take input from user, the code crashes after taking some inputs. Please could you help me out and correct my code and point my flaws. Thank you.
#include <iostream>
//2d array
using namespace std;
int main()
{
int row;
int col_x;
cout << "Enter the row number:" << endl;
cin >> row;
//cout<<"Enter the column number:"<<endl;
//cin>>col;
int **a = new int *[row];
for (int r = 0; r < row; r++)
{
cout << "Enter the column no.of array " << r << endl;
cin >> col_x;
a[r] = new int[col_x];
cout << "Enter the elements in the array:" << endl;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col_x; j++)
{
cin >> a[i][j];
}
}
cout << "The elements in the array:" << endl;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col_x; j++)
{
cout << a[i][j] << " ";
}
cout << endl;
}
}
delete[] a;
a = NULL;
return 0;
}
There was an extra for loop. Also, you have to store the size of each row.
And make the proper deallocation of the 2D array.
#include <iostream>
//2d array
using namespace std;
int main()
{
int row;
cout<<"Enter the row number:"<<endl;
cin>>row;
int **a=new int *[row];
int *col_x = new int [row];
for(int r=0;r<row;r++){
cout<<"Enter the column no.of array "<<r<<endl;
cin>>col_x[r];
a[r]=new int[col_x[r]];
cout<<"Enter the elements in the array:"<<endl;
for(int j=0;j<col_x[r];j++){
cin>>a[r][j];
}
}
cout<<"The elements in the array:"<<endl;
for(int i=0;i<row;i++){
for(int j=0;j<col_x[i];j++){
cout<<a[i][j]<<" ";
}
cout<<endl;
}
for (int i=0; i<row; ++i)
delete[] a[i];
delete []a;
delete []col_x;
return 0;
}
The way you are getting the input from the user is very vague, and is prone to accessing invalid memory. You are getting the same row many times in the inner loop.
Try something like this:
#include <iostream>
//2d array
using namespace std;
int main() {
int row;
int col_x;
cout << "Enter the row number:" << endl;
cin >> row;
//cout<<"Enter the column number:"<<endl;
//cin>>col;
int ** a = new int * [row];
for (int r = 0; r < row; r++) {
cout << "Enter the column no.of array " << r << endl;
cin >> col_x;
a[r] = new int[col_x];
cout << "Enter the elements in the array:" << endl;
for (int j = 0; j < col_x; j++) {
cin >> a[r][j];
}
}
cout << "The elements in the array:" << endl;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col_x; j++) {
cout << a[i][j] << " ";
}
cout << endl;
}
delete[] a;
a = NULL;
return 0;
}
Also, note that col_x will hold only the size of the last row. So, it's not working for the printing at the end of the code.
Not sure what you are trying to achieve, but the main issue with above code is, that you are accessing non-existing elements of your array. Maybe your loop over r should end in line 18? Even then, you would have to store the number of columns per row in some external variable. I would suggest to use a std::vector as the container instead of fixed arrays, in your case a std::vector< std::vector<int> >. The vector class has a method size() which stores its actual size.
Since you are using C++, you should take advantage of the containers it provides for you to store your data, in this case a vector of vectors would be appropriate:
Live Sample
#include <iostream>
#include <vector>
using namespace std; //<-- for test, souldn't be used
int main() {
int rows, cols, temp;
vector<vector<int>> matrix;
cout << "Enter the row number:" << endl;
cin >> rows;
for (int i = 0; i < rows; i++){
vector<int> v;
cout << "Enter the column no.of array " << i << endl;
cin >> cols;
cout << "The elements in the array:" << endl;
for (int j = 0; j < cols; j++){
cin >> temp;
v.push_back(temp);
}
matrix.push_back(v);
}
cout << endl;
for( auto i: matrix){ //print results
for(int j: i)
cout << j << " ";
cout << endl;
}
}

Error: Cannot bind 'std::istream {aka std::basic_istream<char>}' lvalue to 'std::basic_istream<char>&&'

I am taking an input from user for the size of an array, and then the elements of it.
In the below code, cin>>A[i] in the first for loop is giving me an error.
From other questions similar to this one, it's a simple operator error, and the script is similar to working three dimensional ones I've seen. Is new creating a 3 dimensional array by default, meaning I'd need to define columns too? If not, where would I be missing the operator?
int** A;
int s;
cin >> s;
A = new int*[s];
for(int i=0;i<s;i++)
{
A[i]=new int[s];
cout<< "Enter value: ";
cin>>A[i];
}
cout<< "Array:\n";
for(int j=0;j<s;j++)
{
cout << A[j] << " ";
}
A[] is an int* pointer, not an int value.
There is no operator>> that can read an int value into an int* pointer. Since you want to read an int value, you have to read into an int variable, so change A[i] in your 1st loop to *A[i] instead:
cin >> *A[i];
You need to do the same with A[j] in the 2nd loop:
cout << *A[j] << " ";
This is because there is no operator<< to write an int value from an int* pointer, but there is an operator<< that can write the value of a memory address held by a void* pointer, and int* is implicitly convertible to void*.
Don't forget to delete[] your arrays when you are done with them:
int s;
cin >> s;
int** A = new int*[s];
for(int i = 0; i < s; ++i)
A[i] = new int[s];
for(int i = 0; i < s; ++i)
{
cout << "Enter value: ";
cin >> *A[i];
}
cout << "Array:\n";
for(int j = 0; j < s; ++j)
cout << *A[j] << " ";
for(int j = 0; j < s; ++j)
delete[] A[j];
delete[] A;
That being said, you are wasting memory for the second dimension when s > 1, since you are filling in and using only the 1st column and ignoring additional columns. The code you showed only really needs a 1-dimensional array instead:
int s;
cin >> s;
int* A = new int[s];
for(int i = 0; i < s; ++i)
{
cout << "Enter value: ";
cin >> A[i];
}
cout << "Array:\n";
for(int j = 0; j < s; ++j)
cout << A[j] << " ";
delete[] A;
If you really want a 2-dimensional array, try something more like this instead:
int rows, columns;
cin >> rows;
cin >> columns;
int** A = new int*[rows];
for(int i = 0; i < rows; ++i)
A[i] = new int[columns];
for(int i = 0; i < rows; ++i)
{
for(int j = 0; j < columns; ++j)
{
cout << "Enter value for (" << i << "," << j << "): ";
cin >> A[i][j];
}
}
cout << "Array:\n";
for(int i = 0; i < rows; ++i)
{
for(int j = 0; j < columns; ++j)
cout << A[i][j] << " ";
cout << endl;
}
for(int i = 0; i < rows; ++i)
delete A[i];
delete[] A;
That being said, you really should be using std::vector instead of new[] directly.
What array do you want to create? Two-dimensional SxS, or just S-sized?
Because you are creating an array of arrays, while trying to access it as a single-dimensional.
Changing int** A to int* A, A = new int*[s] to A = new int[s], and getting rid of A[i]=new int[s] in the first loop makes the code correct.

C++ Scope issue: Creating a matrix class without wasting space

Here's a tiny little class that's bothering me:
class matrix{
string name;
int rowSize, columnSize;
// I could declare double m[100][100]; here but that would be ugly
public:
void createMat(){
cout << "Enter Matrix Name:";
cin >> name;
cout << "Enter number of rows: ";
cin >> rowSize;
cout << "Enter no. of columns: ";
cin >> columnSize;
double m[rowSize][columnSize]; //needs to be available to readMat()
cout << "Enter matrix (row wise):\n";
for(int i = 0; i < rowSize; i++){
for(int j = 0; j < columnSize; j++){cin >> m[i][j];}
cout<<'\n';
}
}
void readMat(){
cout << "Matrix " << name << " :\n";
for(int i = 0 ; i < rowSize; i++){
for(int j = 0; j < columnSize; j++){ cout << m[i][j] << ' ';}
cout<<'\n';
}
}
};
How can I make m available to both createMat() and readMat() in an optimal way?
Is trying to allow the user to enter the dimensions of the matrix unnecessary?
From my point of view, I feel that me defining the maximum size of the matrix would be too limiting in case more elements are required or too much if not as many elements are required.
You should use a dynamic-sized block of memory, and allocate it at run-time on the basis of user-input. Here, I use std::vector:
class matrix{
std::string name;
int rowSize, columnSize;
std::vector<double> m;
public:
void createMat(){
std::cout << "Enter Matrix Name:";
std::cin >> name;
std::cout << "Enter number of rows: ";
std::cin >> rowSize;
std::cout << "Enter no. of columns: ";
std::cin >> columnSize;
m.resize(rowSize*columnSize);
std::cout << "Enter matrix (row wise):\n";
for(int i = 0; i < rowSize; i++){
for(int j = 0; j < columnSize; j++){
std::cin >> m[i*columnSize+j];
}
std::cout<<'\n';
}
}
void readMat() {
std::cout << "Matrix " << name << " :\n";
for(int i = 0 ; i < rowSize; i++){
for(int j = 0; j < columnSize; j++) {
std::cout << m[i*columnSize+j] << ' ';
}
std::cout<<'\n';
}
}
};
My answers to your questions are:
Make it a class member (as obvious as it sounds, but what kind of answer did you expect?)
Most likely it makes sense to allow the user to set the matrix size... but it really depends on what you need.
I would do a few things differently, in particular:
Instead of createMat() I would use the class constructor do carry out initialization chores (constructors exist for this very reason).
I would then store the elements inside a private 1D array element[rowSize*columnSize] (to be dynamically allocated inside the constructor).
Then I would create the void setElement(i,j) and double getElement(i,j) methods.
(Consider checking out the EIGEN library, a very slick and easy to use linear algebra library, with some Matlab-like flavor)
you need to define m as a class member and go for dynamic memory allocation.
class matrix{
string name;
int rowSize, columnSize;
double **m;
void createMat(){
m = new double*[rowSize];
for(int i = 0; i < rowSize; ++i)
m[i] = new double[columnSize];
}
}
here's a detailed tutorial: http://www.cs.umb.edu/~mweiss/cs410_f04/ppts/cs410-7.pdf

Multi Dimension Arrays issue

OK so basically i want this code to get the user to input a value each time into the array and they get to specify the amount of rows and columns. I think i that the problem is that each time the user enters the value it goes into the correct column but also into both rows so by the end it only prints out the last lot of numbers the user had entered in all of the rows.
Sorry if that was hard to understand as this is my first post to this site and as you can probably tell i am only learning c++. So if you could help it would be greatly appreciated.
#include <iostream>
using namespace std;
int main()
{
int row;
int column;
int value[row][column];
cout << "How Many Rows?\n";
cin >> row;
cout << "How Many Columns\n";
cin >> column;
for(int x = 0; x<row; x++) {
for(int y = 0; y<column; y++) {
cout << "Enter Value Now\n";
cin >> value[x][y];
}
cout << endl;
}
cout << endl;
for(int a = 0; a < row; a++) {
for(int b = 0; b < column; b++) {
cout << value[a][b] << " ";
}
cout << endl;
}
}
int value[row][column];
declares an array whose dimensions are based on 2 uninitialised values.
If you don't have to use a C-style array, you could use
std::vector<std::vector<int>> value;
and choose its dimensions based on user input.
Alternatively, you could continue to use a C-style array if you allocate it like
int** value;
// input row/column
value = new int*[row];
for (int i=0; i<row; i++) {
value[i] = new int[column];
}
If you use the latter approach, make sure to also delete all dynamically allocated memory later.