3

I want to use a two dimensional int array which is returned from a function how should I define the function return value ? I used int** but the compiler gave error:

int**  tableCreator(){
    int** table=new int[10][10];
    for(int xxx=1;xxx<10;xxx++){
        for(int yyy=1;yyy<10;yyy++){
            table[xxx][yyy]=xxx*yyy;
        }
    }
    return(table);  //Here:cannot convert from 'int (*)[10]' to 'int **'
}
MrHs
  • 49
  • 1
  • 1
  • 5

4 Answers4

6

Try this:

#include <cstdio>
#include <cstdlib>


int** createTable(int rows, int columns){
    int** table = new int*[rows];
    for(int i = 0; i < rows; i++) {
        table[i] = new int[columns]; 
        for(int j = 0; j < columns; j++){ table[i][j] = (i+j); }// sample set value;    
    }
    return table;
}
void freeTable(int** table, int rows){
    if(table){
        for(int i = 0; i < rows; i++){ if(table[i]){ delete[] table[i]; } }
        delete[] table;    
    }
}
void printTable(int** table, int rows, int columns){
    for(int i = 0; i < rows; i++){
        for(int j = 0; j < columns; j++){
            printf("(%d,%d) -> %d\n", i, j, table[i][j]);
        }    
    }
}
int main(int argc, char** argv){
    int** table = createTable(10, 10);
    printTable(table, 10, 10);
    freeTable(table, 10);
    return 0;
}

You need the second loop to allocate a 2-d array in C and similar operation to free it. a two-D array is in essence an array of arrays so can be expressed as a pointer array. the loop initializes the arrays pointed to the pointers.

Clarifying as per conversation with @Eric Postpischil below: changed createTable to take row/column count for truly dynamic allocation.

mohaps
  • 1,010
  • 5
  • 10
  • The statement “You need two loops to allocate a 2-d array in C and similar operation to free it.” is false. Multidimensional arrays with fixed sizes in all but the outermost dimension are easily allocated with a single `new` and deallocated with a single `delete`, and using multiple `new` and `delete` calls is wasteful. Variable-length arrays may be supported in various ways that do not require multiple allocations and deallocations. – Eric Postpischil Apr 09 '13 at 17:57
  • but that is only needed if you're allocating the rows of fixed length. e.g. X[10][10]. If your rows are of variable length, a true array of arrays, you do need the loops. – mohaps Apr 09 '13 at 17:58
  • ..and do take a look at the accepted answer :) it does do the loop. if you're dynamically allocating e.g. allocate2DArray(int i, int j) you do have to loop don't you? – mohaps Apr 09 '13 at 18:01
  • By “variable-length arrays”, I meant arrays of forms such as `int a[M]`, `int a[M][N]`, and so on, where one or more of the dimensions was not a compile-time constant. An array of arrays with different lengths is not properly termed a “multidimensional array”; it is a different data structure. The question does not ask for such a data structure. It does not even ask for variable-length arrays as I have described them; it shows only a request for a simple two-dimensional array with constant dimensions. – Eric Postpischil Apr 09 '13 at 18:02
  • Agreed, Eric. that's what I was going for. Thanks for the clarification. I've clarified in the next comment I left. The loop is needed for dynamic allocation. and personally, I prefer 1-D arrays and accessing via y*W+x. much easier to manage – mohaps Apr 09 '13 at 18:03
5
int** table=new int[10][10];

this is wrong. you cannot allocate space for 2D dynamic array in this way in C/C++.

Meanwhile, you declared array size as 10, so indices are from 0-9, but you are trying to assign values to index 10 in your nested for loops, which is not right too.

You may do the following for allocation:

int** table = new int*[10];
for (int i = 0; i < 10; ++i)
{
   table[i] = new int[10];
}
taocp
  • 23,276
  • 10
  • 49
  • 62
  • 2
    If the dimensions are known at compile time, you can allocate space for a two-dimensional array this way. That is, the allocation `new int[10][10]` is correct. The declaration of `table` would need to be changed. If the array is rectangular (does not have rows of different lengths), then allocating multiple pointers and using pointers to pointers is wasteful. The allocation can still be performed in a single call, and multiple dimensions can be supported with a helper class or other constructions. – Eric Postpischil Apr 09 '13 at 18:05
  • Additionally, creating pointers to pointers causes multiple pointer lookups whenever the table is used, and it interferes with the compiler optimizing the code. When there are pointers to pointers, it can be difficult for the compiler to determine they in fact point to different things and therefore cannot alias each other. When the table is passed as a pointer to a single object, the compiler knows that references to different indices are different places in memory. This allows code rearrangement that may improve execution time. – Eric Postpischil Apr 09 '13 at 18:07
3

Usually, the type used to point to an array is a pointer to an element of the array. Since a two-dimensional array of int is an array of array of int, you want a pointer to array of int. The C++ syntax for this type is int (*)[N], for some dimension N. This code demonstrates:

#define N   10

int (*tableCreator())[N]
{
    int (*table)[N] = new int[N][N];

    for (int i = 0; i < N; ++i)
        for (int j = 0; j < N; ++j)
            table[i][j] = i*j;

    return table;
}


#include <iostream>


int main()
{
    int (*t)[N] = tableCreator();

    for (int i = 0; i < N; ++i)
    {
        for (int j = 0; j < N; ++j)
            std::cout << t[i][j] << ' ';
        std::cout << '\n';
    }

    delete [] t;

    return 0;
}
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
0

I. Arrays are not pointers.

II. Why not vector<vector<int> >?

III. If not, then:

typedef int Int10Array[10];
Int10Array *arr = new Int10Array[10];

IV. Why write past the bounds? Do you want explicit nasal demons?

for(int xxx = 0; xxx < 10; xxx++)
             ^^^      ^^^^