Hy guys, I actually Trying to create a 2D Array in c++ but not able to create that, When I execute the following statement
int arr=new int[10][10]
It gives me error and when I search on google it shows me 2D array in c++ is array of pointers which is declare like the below statements
int** a = new int*[rowCount];
for(int i = 0; i < rowCount; ++i)
a[i] = new int[colCount];
I got the logic which is a is a pointer to pointer to the matrix but now I am not able understand the logic like how can i point to the data on this matrix, Suppose to see the number store in index a[0][0] should i write
cout<<a[0][0]
or not, I am not able to get the logic how this pointer to pointer will work when with the pointers pointing to the matrix, and one more thing is that I am not able to pass it as an argument to a function. The code for passing it as a parameter is given below
void displayArray(int a[10][10])
{
for (int i=0; i<10; i++)
{
for(int j=0; j<10; j++)
{
cout<<*a[i][j]<<"\t";
}
cout<<endl;
}
}
int main()
{
int** a = new int*[10];
for(int i = 0; i < 10; ++i)
a[i] = new int[10];
displayArray(**a);
}
It giving me the following error
error: invalid conversion from ‘int’ to ‘int (*)[10]’ [-fpermissive]
Actually I am not able to get any sense of how to use the pointer to pointer in a matrix, it's too complex compared to other languages where we just need to use new operator and can access them with their dimensions, No need of this pointer to pointer concept. Please help me understanding the whole logic of this 2d dynamic array of c++.
you need to get the parameter in your function as pointer
void displayArray(int **a)
{
for (int i=0; i<10; i++)
{
for(int j=0; j<10; j++)
{
cout<< a[i][j] <<"\t";
}
cout<<endl;
}
}
int main()
{
int** a = new int*[10];
for(int i = 0; i < 10; ++i)
a[i] = new int[10];
displayArray(a);
}
it prints 10 rows and columns of value 0 because the 2D array is uninitialized
Related
I am trying to build some .cpp code, in an XCode project. I have a very simple function that converts a matrix of data type cv::Mat (from opencv), to a simple two-dimensional c++ array.
The function looks something like this:
int* myClass::convertMatrix(cv::Mat cvmat){
int r = cvmat.rows;
int c = cvmat.cols;
int newmat[r][c];
for(int i=0; i<r; i++){
for(int j=0; j<c; j++){
newmat[i][j] = cvmat.at<int>(i, j);
}
}
return newmat;
}
I can't figure out what's wrong. I know "lvalue" refers to a specific memory location, but what does this have to do with me returning a matrix?
You're trying to return a pointer to a temporary variable inside that function.
After the function is being returned, that variable is automatically being cleaned up by the compiler.
Also, you are trying to create a stack-allocated array with parameters that are unknown at compile-time, if you had the size of the array at compile-time, you could have marked r and c as constexpr, if it didn't complain about that consider reading about VLA.
To fix those issues, just allocate the array on the heap:
int** make_2d_array(int r, int c)
{
int** arr = new int*[r];
for(int i = 0; i < r; i++)
arr[i] = new int[c];
return arr;
}
int** myClass::convertMatrix(cv::Mat cvmat){
int r = cvmat.rows;
int c = cvmat.cols;
int** newmat = make_2d_array(r, c);
for(int i=0; i<r; i++){
for(int j=0; j<c; j++){
newmat[i][j] = cvmat.at<int>(i, j);
}
}
return newmat;
}
Don't forget to delete the array when you stopped using it.
I also recommend considering using std::vector for that, so you don't have to worry about deleting the array ( way simpler ):
std::vector<std::vector<int>> newmat(r, std::vector<int>(c));
I am trying to implement a binary tree as a 2d array. I want the user to enter the required height of the tree and the program should give an appropriate size array. Then, I want to print the array, which is why I need to pass it as a parameter. However, I get the following error:
arrayTree/main.cpp|19|error: cannot convert ‘std::__cxx11::string** (*)[maxNumberOfNodes] {aka std::__cxx11::basic_string<char>** (*)[maxNumberOfNodes]}’ to ‘std::__cxx11::string** {aka std::__cxx11::basic_string<char>**}’ for argument ‘1’ to ‘void printTree(std::__cxx11::string*)’|
Please, what is causing the error and how can I fix it?
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
void printTree(string** tree);
int main()
{
int treeHeight = 0;
int maxNumberOfNodes = 1;
cout << "enter tree height";
cin >> treeHeight;
cout << treeHeight<< "\n";
//create an array that can hold every combination for a given tree height
maxNumberOfNodes = pow(2,treeHeight) - 1;
string** tree [3][maxNumberOfNodes];
cout << maxNumberOfNodes;
printTree(tree);
}
void printTree(string** tree){
//not fully implemented yet
for(int i=0; i < sizeof(tree); i++){
cout << "*" << " ";
}
}
string** tree [3][maxNumberOfNodes];
is the syntax of a static 2D array of type string** , where both dimensions have to be declared const.
The difference between a static and a dynamic array is shown in here: Multidimensional variable size array in C++
Instead you want to write something like
string** tree = new string*[3];
for(int i = 0; i < 3; i++)
tree[i] = new string[maxNumberOfNodes];
As #Remy Lebeau commented: Every occurrence of new[] needs to be answered by a delete[] call, like this:
for (int i = 0; i < 3; i++)
delete tree[i];
delete[] tree;
to remove the dynamic allocation from the heap.
Like #drescherjm pointed out sizeof(tree) is not valid, as tree is just a pointer and does not include size information about the array.
You could solve this by additionally passing the dimensions of your array with it:
void printTree (string** tree, int dim, int dim2)
and rewriting the loop to
for(int i = 0; i < dim; i++){
for(int j = 0; j < dim2; j++){
cout << tree[i][j]; //...
}
}
string** tree [3][maxNumberOfNodes];
This declares a 2D array of string** pointers. That is not what you want. You want a 2D array of string objects instead, so drop the pointers:
string tree [3][maxNumberOfNodes];
Also, your printTree() is not implemented correctly. It would need to be implemented more like this instead:
void printTree(string** tree, int height) {
for(int i = 0; i < 3; i++) {
for(int j = 0; j < height; j++) {
// use tree[i][j] as needed ...
}
}
}
That being said, since the value of maxNumberOfNodes is not known until runtime, the string tree [3][maxNumberOfNodes] syntax is declaring a Variable Length Array, which is not officially supported by the C++ standard, only as an extension by a few C++ compilers. You need to use new[] instead to allocate the 2nd dimension:
string* tree [3];
for(int i = 0; i < 3; ++i)
tree[i] = new string[maxNumberOfNodes];
printTree(tree, maxNumberOfNodes);
for(int i = 0; i < 3; ++i)
delete[] tree[i];
Or better, use std::vector instead:
std::vector<string> tree [3];
for(int i = 0; i < 3; ++i)
tree[i].resize(maxNumberOfNodes);
Though, in this latter case, you won't be able to pass tree to a string** function parameter, so you will have to adjust the code accordingly.
the method call is given by
printTree(tree [3][maxNumberOfNodes]);
it's working for me
I want to have a function which initializes dynamic 2d arrays in cpp like below
void initArrays(int n,double **a,double **b,double **c) {
a = new double*[n];
for (int i = 0; i < n; i++)
a[i] = new double[n];
b = new double*[n];
for (int i = 0; i < n; i++)
b[i] = new double[n];
c = new double*[n];
for (int i = 0; i < n; i++)
c[i] = new double[n];
}
The function call completes but it does not initialize the pointers I give as function arguments.
For example if I call this function in the main
double **x,**y,**z;
initArrays(3,x,y,z);
I cannot access
x[0][0]
what am I doing wrong here?
The pointers stay uninitialized because you never assign them a value. The pointers in your init function are copies of the ones that you passed. You can pass the pointers by reference:
void initArrays(int n,double **&a,double **&b,double **&c)
That said, you'll probably be better off with std::vector.
I have this function that reads a textfile and sends the strings to an array and then from that function I send that array and number of elements to my constructor. Now my constructor creates a dynamic 2d-array(I hope). I would like my 2d-arrays rows and columns to be assigned values from the array received.
heres my constructor.
Graph::Graph(string cities[], int n)
{
this->nrOfCities=n;
this->x=n;
this->y=n;
this->graph=new string *[x];
for (int i = 0; i < x; i++)
this->graph[i] =new string[y];
for(int i=0;i<this->x;i++)
for(int j=0;j<this->x;j++)
this->graph[j]=NULL;
for(int i=0;i<=this->x;i++)//I know this last part doesn't work.
for(int j=0;j<this->x;j++)
this->graph[0][j+1]=cities[j];
}
Any kind of help is appreciated.
In order to make a dynamic 2darray you must try s.th. like this:
type** arr2d;
arr2d = new type*[rows];
for(int i=0; i<rows; ++i)
arr2d[i] = new type[cols];
I am making a C++ program that checks if given aray is a latin square. I need to use a dynamic multi-dimensional array that stores given latin square. But I cant pass the array to a function that does the checking...
Currently I have such code for calling the function:
int squaretest(int **p, int n, int sum) {
//some code
};
And this code is for creating the array:
int main() {
//some code. n - length of one row, sum - sum of elements in one row.
int a;
int **lsquare;
lsquare = new int*[n];
for (int i=0;i<=n-1;i++) for (int j=0;j<=n-1;j++) {
cin >>a;
lsquare[i][j] = a;
}
blocktest(lsquare,n,sum);
//some code
};
The code compiles (i am using Geany IDE and G++ compiler) but when I run it in terminal, after the first imput, that has to be stored in block[0][0] I get Segmentation fault error. What's wrong with my code and what is the correct sollution?
To be able to do that.. You actually need to do this:
int **lsquare = new int*[n];
for (int i=0; i<n; ++i)
lquare[i] = new int[n];
for (int i=0; i<n; i++)
for (int j=0; j<n; j++)
cin >> lsquare[i][j];
blocktest(lsquare,n,sum);
The better system would be to do:
int *lsquare = new int[n*n];
for (int i=0; i<n; ++i)
for (int j=0; j<n; ++j)
cin >> lsquare[i + j*n];
blocktest(lsquare, n, sum);
You forgot to allocate memory for second dimension of the matrix.
int **lsquare;
lsquare = new int*[n];
for (int i=0; i<n; ++i){
lsquare[i] = new int[n];
....}
nobody writes
for (int i=0;i<=n-1;i++){...}
Do instead
for (int i=0; i<n; ++i){...}
You have an array of pointers in lsquare.
You might want to just do something like:
lsquare = new int[n * n];
That way you can then fill in this square, but the type is then:
int *lsquare
What you are actually creating an array of arrays. Not only do you need to allocate the array of arrays using new, but also you must allocate all n arrays. You'll want to have the outer loop of your nested for loop allocate each of the n sub-arrays.
lsquare = new int*[n];
for (int i=0;i<=n-1;i++)
{
lsquare[i] = new int[n];
for (int j = 0;j<=n-1;j++)
{
//...
You made yourself a pointer pointer that can be used as a matrix, allocated one row for it, then proceeded to act like you'd allocated an entire n*n matrix. You will indeed get a segfault if you run that.
You need to allocate enough space for n*n elements, not just n of them.
A less error-prone solution might be to use a std::vector of std::vectors.
You have to allocate space for the second dimension too, add this after you allocate lsquare:
for(int i = 0; i < n; ++i)
{
lsquare[i] = new int[n];
}