1

To make a two dimensional array, I'm currently using the following:

int * own;

own = (int *)calloc(mem_size, sizeof(int));

for (i=0;i<mem_size;i++){
    own[i] = (int *)calloc(3, sizeof(int));
}

However, every time I reference own[i][j], I get an error saying that the subscripted value is neither array nor pointer nor vector.

db2791
  • 1,040
  • 6
  • 17
  • 30
  • 5
    `own` should be a `int**`. – Daniel Kamil Kozar Apr 30 '15 at 20:21
  • 1
    Often it's best to model a 2d array as a contiguous block and use i x rows + j to access elements. Consider this as an alternative. – Bathsheba Apr 30 '15 at 20:24
  • 5
    To be more precise, this is *not* a 2D array, but only an emulation of such a thing through pointers to pointers. Don't do that if you mustn't. `int (*own)[n] = malloc(sizeof(int[m][n]));` is all you need with a decent C compiler. – Jens Gustedt Apr 30 '15 at 21:10
  • @JensGustedt: you should make that an answer - it is by no means an obvious technique. In fact, I don't think I've ever seen it used before. (if you have the time and inclination, it would be nice to expand on what constitutes a decent or inadequate compiler). – Michael Burr Apr 30 '15 at 21:23
  • @MichaelBurr, this wouldn't be appropriate as an answer here, the question is more specific than that. And I also did that several times, blogged on it, ... , just spread the word. https://gustedt.wordpress.com/2011/01/09/dont-be-afraid-of-variably-modified-types/ – Jens Gustedt May 01 '15 at 07:59

5 Answers5

7

However, every time I reference own[i][j], I get an error saying that the subscripted value is neither array nor pointer nor vector.

That's right. own[i] is equivalent to *(own + i), which has type int. You cannot apply the subscript operator to an int.

Note that what your code appears to be trying to create is not a two-dimensional array, but rather an array of pointers. If that's really what you want then own should have type int **, and you should adjust the first calloc() call accordingly. If you really want dynamic allocation of a 2D array, though, then that would be:

int (*own)[3];

own = calloc(mem_size, sizeof(*own));

Note that there is no need then to allocate (or free) the rows separately.

Note also, however, that if you do not ever need to reallocate own before it goes out of scope, if you can assume at least a C99 compiler, and if mem_size is will never be too large then you can do this even more easily via a variable-length array:

int own[mem_size][3] = {{0}};

No explicit dynamic allocation or deallocation is needed at all in that case, and the initializer can be omitted if unneeded. (I include the initializer because calloc() performs equivalent initialization of the allocated space.) "Too large" should be interpreted in relation to the array being allocated on the stack.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
6

Use:

int ** own; // int**, not int*
own = calloc(mem_size, sizeof(int*)); //int*, not int
                                      // And remove the explicit cast.
R Sahu
  • 204,454
  • 14
  • 159
  • 270
1

Because own is declared as having type int *

int * own;

then own[i] is a scalar object of type int and you may not apply to it the subscript operator.

You could write the following way

int ( *own )[3] = calloc( mem_size, 3 * sizeof( int ) );

The other way is the following

int **own = malloc( mem_size * sizeof( int * ) );

for ( i = 0; i < mem_size; i++ ) own[i] = calloc( 3, sizeof( int ) );
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

Wrong type for 2-D array - well pointed out by many.

Different suggested solution.

When allocating, use the sizeof the variable and not sizeof the type. Less likely to get it wrong - easier to maintain.

//int * own;
int **own;

own = calloc(row_count, sizeof *own);
for (i=0; i<row_count; i++){
  own[i] = calloc(column_count, sizeof *(own[i]));
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0
int *own = calloc(100, sizeof(int));

To build a array 2D array in memory is like this => enter image description here

So it can be accessed using such a formula

*(own + rows*y +x)

Using this type of array is very simple and open, for example when we have 100 cells from memory and we can make it into an array with a size of 100 divisible.
For example, in 100 homes, a array of this size can be provided =>
[1][100]= (own + 1y +x)
[2][50]= (own + 2y +x)
[4][25]= (own + 4y +x)
[5][20]= (own + 5y +x)
[10][10] = (own + 10y +x)
Sorry if I was not right because I speak Persian and I do not know much English


Example:
int *aPtr = calloc(100, sizeof(int));
for(int y=0;y<4;y++){
    for(int x=0;x<25;x++){
        *(own + 25*y +x) = 1;
    }
}
ali naderi
  • 19
  • 2