3

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?

4
  • @coincoin I think you should use new[] instead of malloc() in C++. Commented Dec 9, 2015 at 15:39
  • I think you should use neither and use std::vector instead. Commented Dec 9, 2015 at 15:39
  • dont write C code in C++ Commented Dec 9, 2015 at 15:41
  • Of course my bad I was sure it was a C question ... :) Commented Dec 9, 2015 at 15:41

4 Answers 4

4

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.

Sign up to request clarification or add additional context in comments.

2 Comments

You'll want a[i*col+j]
Thank you for giving me C oriented answer, but i guess vector is the way to go for c++
3

Problems that I see

  1. C++ does not allow declaration of variable length arrays. Hence,

    int b[r][r];
    

    is wrong.

  2. 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.

Comments

2

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

3 Comments

Using reference to avoid copying many data might be good. void printHalf(std::vector<std::vector<int>> data) -> void printHalf(const std::vector<std::vector<int>>& data)
I would also recommend to use a flatten/linear vector<int> only instead of nested vectors vector<vector<int>>.
@coincoin That is a good suggestion and in production code that is what I would use. I did not want to present that to the OP as I am already changing to using a vector and wanted to leave the code looking as close the the original as I could.
0

you can use extension/type Variable Length Array:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int h,w;
    scanf("%d%d",&h,&w);
    int * arr = malloc(w*h*sizeof(int));
    for(int i=0; i<w*h; i++)
        arr[i] = i;

    typedef int (*arr2_t)[w];
    int (*arr2)[w];
    arr2 = (arr2_t)arr;

    for(int y=0; y<h; y++){
        for(int x=0; x<w; x++)
            printf("%d ",arr2[y][x]);
        printf("\n");
    }
}

I don't know how type can depend on variable, but gcc and clang compile that.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.