2

I try to pass a static two dimensional struct as a reference to a function. But I don't know how to get that done in correct way.

From my understanding, I pass a pointer to the first element of struct test to initfield(). C does know the size of the struct test so I can jump to the specific requested locations of the data. I just don't know how to adress the required data.

Here's my code that hopefully describes what I am looking for.

struct test{
int i;
double d;
};

void initfield(struct test *a, int structsize)
{
    int i, j;
    for (i = 0; i < structsize; i++)
    {
        for (j = 0; j < structsize; j++)
        {
            a[i][j]->i = 1;
            a[i][j]->d = 1.0;
        }
    }
}

int main(void)
{
    int i, j;
    struct test field[8][8];
    initfield(field, 8);
    for (i = 0; i < 8; i++)
    {
        for (j = 0; j < 8; j++)
        {
            printf("test[%i][%i].i = %i", i, j, test.i);
            printf("test[%i][%i].d = %i", i, j, test.d);
        }
    }
    return 0;
}

Update :

I've replaced both printf's with the following :

printf("test[%i][%i].i = %i", i, j, field[i][j].i);
printf("test[%i][%i].d = %lf", i, j, field[i][j].d);

However, I still encounter errors with initfield.

5 Answers 5

1

The problem, is actually, in your initfield() code,

 void initfield(struct test *a, int structsize)

a is of type struct test *, and later, you're doing

 a[i][j]->i = 1;

which expects a to be struct test **

That said,

for (j = 0; j < 8; j++)
    {
        printf("test[%i][%i].i = %i", i, j, test.i);
        printf("test[%i][%i].d = %i", i, j, test.d);
    }

is completely wrong. Neither is there any variable called test, nor you can access a 2-D array using structVar.membervar format. Moreover, you are using %d to print a double, which in turn invokes undefined behaviour.


Solution: You can make use of array properties and pointer arithmetic to achieve what you want.

You have to change the loop inside the initfield() code, like

for (i = 0; i < structsize; i++)
{
    for (j = 0; j < structsize; j++)
    {
        ((a+(i*structsize))+j)->i = 7;   //I changed the value to store, just like that
        ((a+(i*structsize))+j)->d = 2.0; //I changed the value to store, just like that
    }
}

and, in main(), use %f to print the values.

A Live variant

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

2 Comments

Thanks for your reply! I edited the code in main(), youre right complete wrong. I also understand now that in my code a is single dimensional. should be two dimensional. however if initfield(struct test **a, int structsize) then i still have errors...
@SteffenKirner please do not remove information from your questions if it invalidates already posted answers. You can add updates if only part of your problem is solved, or post another question is you encountered a different problem.
1

First, structsize is not a good identifier name. It's not the size of the struct, it's the size of one dimension of the array. I'd implement it with parameters x and y, or width and heigth, or any better names for the two dimensions.

field is also a bad name. A field is often used to call a member of a struct. It is very confusing to use the identifier field to call an array of array of structs.

Then to your problem: field is an array of array of structs. In function parameter, this is equivalent to a pointer to a pointer.

The first parameter of initfield should be of type struct test **. Then later in the function, you dereference twice with your [] operators:

  • a is of type struct test **
  • a[i] is of type struct test *
  • a[i][j] is of type struct test

To access the fields of a[i][j], you need the . operator since its a struct test: a[i][j].d. The operator -> would work if a[i][j] was of type struct test *, but it isn't.

In this case it doesn't matter: as other have said, you can't access the second dimension of the array without explicitly calculating with the help of the size of the first dimension. a[i][j] does not work, you need some kind of pointer arithmetic: struct test *p = a + i * structsize + j and use p->i and p->d.

In the main function however, the dimensions of field are know, so field[i][j].d works.

Comments

0

You're assuming C can figure out that a inside refers to a square array with side length structsize, although you clearly say that a has type "pointer to struct test", which is not the same.

You need to do the indexing manually, inside the function:

static void initfield(struct test *a00, size_t sidelength)
{
  for(size_t i = 0; i < sidelength; ++i)
  {
    for(size_t j = 0; j < sidelength; ++j)
    {
      struct test *aij = a00 + i * sidelength + j;
      aij->i = 1;
      aij->j = 1.0;
    }
  }
}

I didn't test the above, but something like that should work. It basically just uses simple pointer arithmetic to compute the address of the 2D array element at (i, j) given the address of the one at (0, 0).

Comments

0

It works fine i din't thought about doing calculation the adresses myself. Thanks very much!

Here's my final adapted code which just works perfectly!

struct test{
int i;
double d;
};

void initfield(struct test *a00, int structsize)
{
    int i, j;
    for (i = 0; i < structsize; i++)
    {
        for (j = 0; j < structsize; j++)
        {
            struct test *acurrent = a00 + i * structsize + j;
            acurrent->i = 1;
            acurrent->d = 1.0;
        }
    }
}

int main(void)
{
    int i, j;
    struct test field[8][8];
    initfield(&field[0][0], 8);
    for (i = 0; i < 8; i++)
    {
        for (j = 0; j < 8; j++)
        {
            printf("test[%i][%i].i = %i\n", i, j, field[i][j].i);
            printf("test[%i][%i].d = %lf\n", i, j, field[i][j].d);
        }
    }
    return 0;
}

Comments

0

Best way to do this:

void initfield(size_t x, size_t y, struct test a[x][y]);

Be aware though, C is strange, the above is still a pointer, equivalent to struct test*. If you wish to have a true array pointer type, you'd have to do:

void initfield(size_t x, size_t y, struct test a[x][y])
{
  struct test (*ptr)[x][y] = (void*)a;

or preferably:

struct test (*ptr)[y] = *a;
ptr[i][j] = something; // use the array pointer with sane syntax

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.