Using dynamic multi-dimensional arrays in c++ - c++

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];
}

Related

C++ Variable-sized arrays using stdin and stdout

I'm trying to solve this problem on variable-sized arrays but I'm getting a compilation error. Not exactly sure where I went wrong.
Problem can be accessed in this PDF
My solution attempt is as follows:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int n,q,size,elem,index,smallindex;
//input of n and q
cin>>n>>q;
//declare the array a
int* bigarr = new int[q];
//assign the individual arrays to each element of the array a
for (int i=0; i<n; ++i){
//input of size of the individual array
cin>>size;
int* smallarr = new int[size];
for (int j=0; j<size; ++j){
smallarr[j] = cin>>elem;
}
bigarr[i] = smallarr;
}
//obtain index queries
for (int k=0; k<n; ++k){
cin>>index;
cin>>smallindex;
cout<<bigarr[index][smallindex];
}
}
On this statement:
bigarr[i] = smallarr;
smallarr is an int* pointer, but bigarr is also an int*, ie an array of int, so bigarr[i] is a single int. You can't assign an int* pointer to an int value.
If you want bigarr to be an array of pointers to other arrays, you need to declare bigarr as int** instead of int*, and then use new int*[q] to allocate it.
int** bigarr = new int*[q];
Also, on this statement:
smallarr[j] = cin>>elem;
The expression cin>>elem returns an istream& reference to cin, it does not return the int value read into elem, like you are expecting. So you can't use the result of that expression directly in the assignment to smallarr[j]. You will have to read elem and assign it to smallarr in separate statements:
cin>>elem;
smallarr[j] = elem;
That said, note that your code is leaking all of the allocated arrays since there are no calls to delete[] anywhere. You need to add them:
int** bigarr = new int*[q];
...
for (int i=0; i<n; ++i){
...
int* smallarr = new int[size];
...
bigarr[i] = smallarr;
}
...
for (int i=0; i<n; ++i){
delete[] bigarr[i]; // <-- here
}
delete[] bigarr; // <-- here
Though, you really should be using std::vector instead of using new[]/delete[] manually at all (you already have #include <vector>):
std::vector<std::vector<int> > bigarr(q);
...
for (int i=0; i<n; ++i){
...
std::vector<int> smallarr(size);
for (int j=0; j<size; ++j){
...
smallarr[j] = elem;
}
bigarr[i] = smallarr;
/* alternatively:
bigarr[i].resize(size);
for (int j=0; j<size; ++j){
...
bigarr[i][j] = elem;
}
*/
}
I also see is that you are using q to allocate bigarr, but then you use n to loop through bigarr. You don't need two separate variables. Use either n or q for both tasks, and get rid of the other variable.
Unless you really intend to allocate more slots then you want to fill in. In which case, your outer loop needs to ensure that it doesn't exceed both n and q:
for (int i=0; (i<n) && (i<q); ++i){
Or:
for (int i=0; i<std::min(n,q); ++i){

How many different way exists to define 2D array with pointers in C++?

I try to define a 2D array with C++ with pointers and I don't know how can I define it true? I have some loops in the function and they are start with 1 to n and I want to allocate memory and at the end of function I want to delete allocated memory?
for define it like the following code. please help me to develop it.
int **W;
W = new int* [n];
for (int i=1; i <= n; i++)
W[i] = new int[n];
///////////////////////
for (int k=1;k<=n;k++)
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
do some thing!
///////////////////////
for ( int i = 1; i <= n; i++ )
delete [] W[i];
delete W;
For an array of size n, indices start from 0 - (n-1). Thus array[n] is out of bounds.
int **W;
int n = 3;
W = new int*[n];
for (int i = 0; i < n; i++)
W[i] = new int[n];
for (int i = 0; i < n; i++)
delete[] W[i];
delete W;
You have the general idea correct. But there are some errors in the details. C/C++ use 0-based indices to access arrays.
for (int i=1; i <= n; i++)
W[i] = new int[n];
needs to be
for (int i=0; i < n; i++)
W[i] = new int[n];
Similar changes need to be made in the other for statements.
Also, you need to delete W using the array delete operator. Instead of
delete W;
use
delete [] W;
Having said that, you should use std::vector instead of plain old dynamic arrays. With std::vector, you don't have to worry about deallocation of memory. The destructor of std::vector will take care of deallocating memory.
A 2D array of size n x n where each element is initialized to 0 can be defined simply as:
std::vector<std::vector<int>> array(n, std::vector<int>(n, 0));

cpp two dimensional dynamic array

I'm using c++ and I want to use two dimensional dynamic array. I tried this:
#include<iostream.h>
using namespace std;
void main(){
int const w=2;
int size;
cout<<"enter number of vertex:\n";
cin>>size;
int a[size][w];
for(int i=0; i<size; i++)
for(int j=0; j<w; j++){
cin>>a[i][j];
}
}
but not worded.
and I tried this:
int *a = new a[size][w];
instead of
int a[size][w];
but not worked!
could you help me plz.
thanks a lot.
The correct approach here would be to encapsulate some of the standard containers, that will manage memory for you, inside a class that provides a good interface. The common approach there would be an overload of operator() taking two arguments that determine the row and column in the matrix.
That aside, what you are trying to create manually is an array of dynamic size of arrays of constant size 2. With the aid of typedef you can write that in a simple to understand manner:
const int w = 2;
typedef int array2int[w];
int size = some_dynamic_value();
array2int *p = new array2int[size];
Without the typedef, the syntax is a bit more convoluted, but doable:
int (*p)[w] = new int [size][w];
In both cases you would release memory with the same simple statement:
delete [] p;
The difference with the approaches doing double pointers (int **) is that the memory layout of the array is really that of an array of two dimensions, rather than a jump table into multiple separately allocated unidimensional arrays, providing better locality of data. The number of allocations is lower: one allocation vs. size + 1 allocations, reducing the memory fragmentation. It also reduces the potential from memory leaks (a single pointer is allocated, either you leak everything or you don't leak at all).
For a dynamic sized array you must dynamically allocate it. Instead of
int *a = new a[size][w];
Use
int** a = new int*[size];
for(int i = 0; i < size; i++)
a[i] = new int[w];
OP is saying he wants to create a 2 dimensional array where one dimension is already known and constant and the other dimension is dynamic.. Not sure if I got it right but here goes:
int main() {
const int w = 2;
int size = 10;
int* arr[w];
for (int i = 0; i < w; ++i)
arr[i] = new int[size];
//do whatever with arr..
//std::cout<<arr[0][0];
for (int i = 0; i < w; ++i)
for (int j = 0; j < size; ++j)
std::cout<<arr[i][j];
for (int i = 0; i < w; ++i)
delete[] arr[i];
return 0;
}
You can not do that in c++, please read about dynamic memory allocation
the code below should work
int* twoDimentionalArray = new [size*w]

make one arrays content into another 2d arrays rows & colums

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];

dynamically allocating atwo dimensional array where each row contains variable number of elements & freeing it in c++

How can I dynamically allocate a two dimensional array where each row contains variable element? How can I free this memory?
Actually you probably want a vector of vectors, something like this:
std::vector<std::vector<int> > vector_2d;
This way you'll benefit from the automatic memory management of the vector rather than having to manually manage the memory of an array of pointers to arrays of data.
You would need need to use pointers:
int ** a;
a = new (int*)[5];
for(int i = 0; i<5; i++)
{
a[i] = new int[x]; //where x is the size of this row
}
Something like this should work, but I didn't test it.
Just for the sake of completeness:
int ** a;
a = new (int*)[5];
for(int i = 0; i<5; i++)
{
a[i] = new int[x]; //where x is the size of this row
}
for(int i = 0; i<5; i++)
{
delete[] a[i];
}
detete[] a;