Sending variable size 2D array to function in C++ - c++

I am trying to write a function which takes variable size array and prints it. But i am having problem in function declaration argument list while compiling.
The error is:
cannot convert ‘int (*)[(((sizetype)(((ssizetype)r) + -1)) + 1)]’ to ‘int**’ for argument ‘1’ to ‘void printHalf(int**, int, int)’
printHalf( b, r, r);
Code:
#include <iostream>
using namespace std;
void printHalf( int **a, int row, int col ) { // Problem is here.
for( int i=0; i < row; i++) {
for( int j=0; j < col; j++) {
if( i <= j) {
cout << a[i][j] << " ";
}
}
cout << endl;
}
}
int main() {
int r;
cout << "No. of rows: ";
cin >> r;
int b[r][r];
for( int i=0; i < r; i++) {
for( int j=0; j < r; j++) {
cin >> b[i][j];
}
}
printHalf( b, r, r);
return 0;
}
What is causing this error, and how do i pass various arrays to function?

A 2D array of [N][M] is laid out the same in memory as a 1D array of [N*M].
void printHalf( int *a, int row, int col ) { // Problem is here.
for( int i=0; i < row; i++) {
for( int j=0; j < col; j++) {
if( i <= j) {
cout << a[i*col+j] << " ";
}
}
cout << endl;
}
}
Then you can call it with printHalf( &b[0][0], r, r).
Your fundamental misunderstanding is the relationship between arrays and pointers. Arrays aren't pointers. An int** can be viewed as an array of int*, which isn't what you have. b[0] gets you an int[r]. This is different to an int*. b[0][0] gets you the first int.

Problems that I see
C++ does not allow declaration of variable length arrays. Hence,
int b[r][r];
is wrong.
A one dimensional array decays to a pointer but a two dimensional array does not decay to a pointer to pointer. Even if you had b defined correctly, such as:
int b[10][10];
you cannot use b as an argument to a function that expects an int**.
Solution
I suggest use of std::vector.
std::vector<std::vector<int>> b(r, std::vector<int>(r));
Change the function printHalf accordingly.
void printHalf( std::vector<std::vector<int>> const& b ) { ... }
You don't need row and col as arguments since that information can be obtained from the std::vector.

First off int b[r][r]; is a variable length array and is not standard in C++. If you need a container that can be sized at run time then I suggest you use a std::vector
std::vector<std::vector<int>> data(r, std::vector<int>(r, 0)); // create vector and set all elements to 0
Then your print function would become
void printHalf(const std::vector<std::vector<int>>& data) {
for( std::size_t i=0; i < data.size(); i++) {
for( std::size_t j=0; j < data[i].size(); j++) {
if( i <= j) {
cout << a[i][j] << " ";
}
}
cout << endl;
}
}

Related

2d vector input and display through function

I have written this code to input and display a 2d vector matrix but it is not working can someone help me identify the errors.
The main function is only taking input a and b and the function are not called properly.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<vector<int>> input(int a, int b)
{
vector<vector<int>> arr;
for (int i = 0; i < arr.size(); i++)
{
for (int j = 0; j < arr[i].size(); j++)
{
cin >> arr[i][j];
}
}
return arr;
}
void display(vector<vector<int>> arr)
{
for (int i = 0; i < arr.size(); i++)
{
for (int j = 0; j < arr[i].size(); j++)
{
cout << arr[i][j] << " ";
}
}
cout << "\n";
}
int main()
{
int a, b;
cin >> a >> b;
vector<vector<int>> arr;
arr = input(a, b);
display(arr);
}
In your input function the vector arr is empty. That means arr.size() will return 0 and the loops will not happen.
If you know the dimensions of the vectors from the beginning (I assume they are the (pretty badly named) a and b variables) then you can use that to set the size:
vector<vector<int>> input(int a,int b)
{
// Create a vector of a elements, each element is in turn a vector of b elements
vector<vector<int>> arr(a, vector<int>(b));
// ...
}
See e.g. this std::vector constructor reference for more information about the constructors used (alternative 2 and 3).

Access multidimensional array passed to function

I am looking for a way to access a multidimensional Array that is passed via pointer. I followed the question here (Create a pointer to two-dimensional array) to create my array and a pointer to it. I could even pass the pointer to the function, but I can't use the pointer to access the array values. What's the correct way to access the values inside the function.
main.cpp:
MyArrayGenerator theArrGen = MyArrayGenerator();
const int size = 9;
int generatorArray[size][size][10];
theArrGen.generateArray(size, generatorArray[size][size+1]);
The method in my class:
void MyArrayGenerator::generateArray(int size,int* pointerToMultiDimArr)
{
int height = size + 1;
// this ptr points to the array address
int* ptr = pointerToMultiDimArr;
// not working:
ptr[1][1][1] = 123;
}
this throws the compiler error https://msdn.microsoft.com/de-de/library/fhexbxk9.aspx wich means that the pointer is not declared as array.
I guess my method argument needs to change since it wants a pointer and does not know that it will be an array. My question is: How should the method argument look like and how do I access the array in my method after that. Later on I want the user to input the size of the multidimensional array and
const int size = 9;
is just a placeholder
Use pointer notation to access elements! Here is an example to access and use 2d array's pointer this program prints transpose of a matrix
#include<iostream>
int **arr_input(int row, int col)
{
int **arr;
arr = new int*[row];
for (int i = 0; i < row; i++) //array size
{
*(arr + i) = new int[col];
}
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
cin >> *(*(arr + i) + j);
}
} //input array
return arr;
}
void transpose(int**arr, int row, int col)
{
for (size_t i = 0; i < row; i++)
{
for (size_t j = 0; j < col; j++)
{
cout << *(*(arr + j) + i) << " "; //pointer notation//
}
cout << endl;
}
}
void main(){
int row ,col,**ptr1;
cout << "Enter size of Square Matrix: "; cin >> row; col = row;
cout << "\n\tEnter the elements of Matrix\n";
ptr1 = arr_input(row, col); //calling array input function
cout << "\nAdress of pointer is " << ptr1<<endl;
transpose(ptr1, row, col); //calling transpose function
system("pause");
}

C++ 2D Array - Error invalid types ‘int[int]’ for array subscript

I am trying to create MxN matrix using 2D-arrays in C++.
The createMatrix() function asks for user input for matrix items and the printMatrix() function has to print the matrix.
But the printing task is not working (I can't access the array created, I don't understand why)
I receive the error :
matrix.cpp:35:20: error: invalid types ‘int[int]’ for array subscript
cout << matrix[i][j];
The code I'm working with is:
#include "iostream"
using namespace std;
// user input matrix
int createMatrix(int m, int n){
int arr[m][n];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << "A[" << i << "][" << j << "] : ";
cin >> arr[i][j];
}
cout << endl;
}
return arr[m][n];
}
/*
void printMatrix(int matrix[][2], int m, int n){
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << matrix[i][j];
}
}
}
*/
int main(){
int m = 2, n = 2; // m = rows, n = columns
int matrix = createMatrix(m,n);
// printMatrix(matrix, m, n); // not working as sub-routine too, main target to make it work with sub-routine
// to print matrix
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << matrix[i][j];
}
}
return 0;
}
matrix is an int not an int[][]. Since it is an int there is no subscript operator and that is why you are getting the error you are getting. You are also using veriable length arrays which is not standard C++. I would suggest you change your code to use a std::vector like
std::vector<std::vector<int>> createMatrix(int m, int n)
{
std::vector<std::vector<int>> arr(m, std::vector<int>(n));
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << "A[" << i << "][" << j << "] : ";
cin >> arr[i][j];
}
cout << endl;
}
return arr;
}
And then main() would be:
int main(){
int m = 2, n = 2; // m = rows, n = columns
std::vector<std::vector<int>> matrix = createMatrix(m,n);
// printMatrix(matrix, m, n); // not working as sub-routine too, main target to make it work with sub-routine
// to print matrix
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << matrix[i][j];
}
}
return 0;
}
Your matrix is not array. it is int.
You need to work with the pointers.
Yes, createMatrix works but you won't be able to do anything with what it created. Because:
arr[n][m] is local (and out of boundaries by the way). It is not a matrix as you probably thought but an item of arr at position [n][m].
It is not well defined to declare array of fixed sizes with vary sizes that depend on function input.
You need to pass to createMatrix array from the main() as pointer (like you did in printMatrix) and createMatrix should work with it and not something local.
Now regarding your original question:
But the printing task is not working (I can't access the array
created, I don't understand why)
matrix was defined as int, not as array.
int matrix = createMatrix(m,n);

How to work with 3d arrays through pointers in C++

I'm facing some difficulties with pointers for 3D arrays in C++. I've a array of Q[3][N][N] which I want to pass to a function to print the values at [0][i][j] location (and also for [1][i][j] and [2][i][j]). How can I achieve this? Will it be more convenient to use Q[i][j][0] etc?
for 2D, the following piece of code works just fine when I give &Q[0][0] to the *var:
template <typename T>
void print2d(T *var, int I, int J){
cout << endl;
for (int j = 0; j < J; j++){
for (int i = 0; i < I; i++){
cout << setprecision(3) << setw(12) << *(var + (N*i + j));
}
cout << endl;
}
cout << endl;
}
I'm using the same approach to write a similar function for 3D which does not write out the correct values:
Can anybody let me know the correct way to point to the correct address of Q[i][j][1]. In input argument, I'm giving the address of Q[0][0][0]. Should I use different addresses (such as Q[i][j][1]) if I want to write out for that particular value of k?
template <typename T>
void print3d(T *var, int I, int J, int K){
cout << endl;
for (int j = 0; j < J; j++){
for (int i = 0; i < I; i++){
cout << setprecision(3) << setw(12) << *(var + I*J*i + I*j + K);
}
cout << endl;
}
cout << endl;
}
Sample example, N must be const.
But consider using vector.
#include <stdio.h>
#include <iostream>
using namespace std;
const int N = 5;
void func2(int* tab, int A, int B, int C)
{
printf("%d\n", tab[N*N*A + N*B + C] );
}
void func(int tab[3][N][N])
{
for (int i = 0; i < 3; ++i)
for (int j = 0; j < N; ++j, printf("\n"))
for (int k = 0; k < N; ++k)
{
printf("%d ", tab[i][j][k]);
}
}
int main()
{
int tab[3][N][N];
int p = 0;
for (int i = 0; i < 3; ++i)
for (int j = 0; j < N; ++j)
for (int k = 0; k < N; ++k)
{
tab[i][j][k] = p++;
}
func(tab);
printf("\n");
func2((int*)tab, 1, 1, 3);
}
I agree with Adam's answer but cant comment, need more points there.
1) Arrays are not pointers. Multidimensional arrays cannot be passed via a pointer, needs to have all but one dimension constant. Here is an answer to help understand.
Cannot cast array to pointer
How do I pass a reference to a two-dimensional array to a function?
http://www.cplusplus.com/forum/articles/17108/
You might want to try vectors from STL instead.
2) Templates are compiled only when there is an instance of it used, that is why its declaration and usage is generally put in one file.
Template Compilation

Replacing values in a 2D array

I have to create a program that allows a user to fill in a (partial) Latin Square of order 4. You can use 0's to represent empty cells. The user will give the number to place, the row and column. The number should only be placed if it does not violate the properties of a partial Latin square and it shouldn't rewrite numbers that have already been placed.
I have an matrix that is outputting all zeroes now. So next I have to replace each of these values by what the user is inputting. The problem is I don't know how to do this.
Here is my code:
#include <iostream>
using namespace std;
const int ORDER = 4;
void fill (int m[], int order);
void outputMatrix (int m[], int order);
void replaceValue (int m[], int order, int n, int row, int column);
int main(){
int matrix[ORDER];
int row;
int column;
int n;
fill (matrix, ORDER);
outputMatrix (matrix, ORDER);
do {
cout << "Enter the number to place, the row and the column, each seperated by a space: ";
cin >> n;
cin >> row;
cin >> column;
}while (n > 0 || n <= ORDER);
if (n <= 0 || n >= ORDER){
cout << "Thank you";
cout << endl;
}
return 0;
}
void fill (int m[], int order){
for (int i = 0; i < order*order; i++){
m[i] = 0;
}
}
void outputMatrix (int m[], int order){
int c = 0;
for (int i = 0; i < order*order; i++){
c++;
cout << m[i] << ' ';
if (c == order){
cout << endl;
c = 0;
}
}
cout << endl;
}
void replaceValue (int m[], int order, int n, int row, int column){
for (int i = 0; i < order; i++){
m[order] = m[row][column];
m[row][column] = n;
}
}
How do I replace values in a Matrix in C++?
If you have a matrix, matrix[row][col] = value; would do the trick. However, I see that you allocate a single array. Make sure you look at this.
EDIT:
I looked closer at you code and you are doing some things wrong.
First:
matrix[ORDER]
will create a single array of ORDER values. If you want and ORDER by ORDER matrix try:
matrix[ORDER][ORDER]
Second:
You are calling:
void fill (int m[], int order){
for (int i = 0; i < order*order; i++){
m[i] = 0;
}
}
with an of size 4 and order == 4. This will loop outside the array and give you problems.
Try something like:
matrix[ORDER][ORDER];
for (int row = 0; row != ORDER; ++row)
{
for (int col = 0; col != ORDER; ++col)
{
matrix[row][col] = 0;
}
}
Hope this helps.
You can't really write arr[i][j] if arr is defined as arr[]. There's no information about the length of the row (how many columns there are).
You could use arrays of type arr[][4], and write your functions like so:
// The & is to pass by reference.
void print(int (&arr)[][4], int length)
{
for(int i = 0; i < length; i++) {
for(int j = 0; j < 4; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
But in my opinion for a low-order multidimensional array like this one, using a typedef for a vector of vectors is the better option:
typedef vector<vector<int> > Matrix;
void print(Matrix& arr)
{
for(int i = 0; i < arr.size(); i++) {
for(int j = 0; j < arr[i].size(); j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
In either case, writing arr[i][j] = k will behave as you expect.
The easiest way to clear/zero your matrix is that:
memset( &matrix, 0, sizeof(matrix));
;-)