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 **'
}
0

4 Answers 4

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.

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

5 Comments

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

2 Comments

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

Comments

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++)
             ^^^      ^^^^

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.