0

so im trying to define a generic ADT. i have a struct that looks like this:

struct grid_type{
    void* table;
    int startX, startY, endX, endY, xDim, yDim;
};

as you can see i have a void pointer which should be able to store various data types. for this instance im trying to point to an int** (two dimensional array) which is returned by this function:

int** CreateInt(int xDim, int yDim){
    int** table = NULL;
    int i, j;
    table = (int**)malloc(xDim*sizeof(int*));
    if (table == NULL){
        puts("failed malloc");
        exit(1);
    }
    for (i = 0; i < xDim; i++){
        table[i] = (int*)malloc(yDim*sizeof(int));
        if (table[i] == NULL){
            puts("failed malloc");
            exit(1);
        }
        for (j = 0; j < yDim; j++){
            table[i][j] = 1;
        }
    }
    return table;
}

pretty basic function. so what im failing to do is reading from this array later, can't seem to access any data. this is how im trying:

void PrintInt(grid* grid){
    int i, j, add = 0;
    for (i = 0; i < grid->xDim; i++){
        for (j = 0; j < grid->yDim; j++){
            add = i*(grid->xDim-1) + j;
            printf("%d   ", *((int*)grid->table+add)); <--- PROBLEM
        }
        printf("\n");
    }
}

and this is how it all happens in the main:

grid1 = CreateGrid((*CreateInt), xDim, yDim, startX, startY, endX, endY);
PrintInt(grid1);

what im getting is 100% jibrish, any ideas?

Felix Kreuk
  • 193
  • 1
  • 9
  • Please tag with the language you're using. – Wooble Jan 09 '14 at 13:20
  • An `int **` is not a two-dimensional array. Also, don't cast `void *` (this includes `grid->table` and the return type of `malloc()`). –  Jan 09 '14 at 13:22
  • Have you tried `int** arr = (int**)(grid->table)` and using `arr` after that? – Kakadu Jan 09 '14 at 13:22
  • @Kakadu Surely you meant `int **array = grid->table;`!? –  Jan 09 '14 at 13:23
  • @H2CO3 I don't remember do we need explicit casting when we use void pointer. If it is not needed, OK – Kakadu Jan 09 '14 at 13:28
  • @Kakadu This is C, not C++. Explicit casts involving `void *` are bad practice. –  Jan 09 '14 at 13:29
  • @H2CO3 ok, so how can i access grid->table? – Felix Kreuk Jan 09 '14 at 13:30
  • 1
    @FelixKreuk You can access it just the way you showed: `grid->table`. If you assign it to a pointer to appropriate type, such as `int **p = grid->table;`, then you can index it as if it was your original pointer (because it *is*). Nothing magical here. –  Jan 09 '14 at 13:31
  • @H2CO3 thanks a lot!, could you perhaps explain to me why the way i originally wrote it didn't work? `*(int**)grid->table+index)` seems like the same just without declaring another var. – Felix Kreuk Jan 09 '14 at 13:35
  • 1
    @FelixKreuk Perhaps operator precedence (and/or misunderstanding of pointer arithmetic)? `(int **)grid->table + index` will increment the original pointer by `index` units and dereference it to obtain an `int *`, that needs yet another level of indirection to get to your `int` element. I don't know if that was what you intended to do, but if not, then here it is why it didn't work. –  Jan 09 '14 at 13:38
  • @H2CO3, thanks that helped alot. 1 last question, how can i assign a new value to an [i][j] place in the array? cant do this `grid->table[i][j] = x;` EDIT: just did it with `int **p = grid->table;` again, but is there a way to change it straight through `grid->table[i][j]` ? – Felix Kreuk Jan 09 '14 at 14:33
  • @FelixKreuk yes, if you cast it to `int **`. But that looks horrible. –  Jan 09 '14 at 14:41
  • @H2CO3, yeah that's what i tried `(int**)grid->table[i][j] = x;` but it doesn't compile, says "unknown size of void*". or maybe i'm doing it wrong? – Felix Kreuk Jan 09 '14 at 19:57
  • @FelixKreuk As I mentioned, operator precedence. You'll need a couple of parentheses. –  Jan 09 '14 at 20:15

1 Answers1

1
void PrintInt(grid* grid){
    int i, j;
    int **table = grid->table;
    for (i = 0; i < grid->xDim; i++){
        for (j = 0; j < grid->yDim; j++){
            printf("%d   ", table[i][j]);
        }
        printf("\n");
    }
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
  • It can't for the addition and subtraction of type `void *`. (Although there may be cases where it operates to expect implementation.) – BLUEPIXY Jan 09 '14 at 17:15