20

I know this question has been asked a lot, but I'm still unclear how to access the structs.

I want to make a global pointer to an array of structs:

typdef struct test
{
    int obj1;
    int obj2;
} test_t;

extern test_t array_t1[1024];
extern test_t array_t2[1024];
extern test_t array_t3[1025];

extern test_t *test_array_ptr;

int main(void)
{
    test_array_ptr = array_t1;

    test_t new_struct = {0, 0};
    (*test_array_ptr)[0] = new_struct;
}

But it gives me warnings. How should I access the specific structs with []?

Similarly, how should I create an array of pointers of struct type? test_t *_array_ptr[2];?

user1539348
  • 513
  • 1
  • 7
  • 20
  • 1
    Shouldn't give you warnings, should give an error. `(*test_array_ptr)[0]` dereferences twice, but there is only one level of stars. – Daniel Fischer Apr 24 '13 at 20:34
  • @DanielFischer: gcc, for example, frequently prints warnings for constructs that are "constraint violations" (about as close as C comes to saying that something is *illegal*). The `-pedantic-errors` option makes it behave more strictly. – Keith Thompson Apr 24 '13 at 20:59
  • @KeithThompson Yes, but for that specific problem, gcc says `deref.c:18:18: error: subscripted value is neither array nor pointer nor vector` without any flags. (Hmm, what's a `vector`, this is C?) For stuff like dereferencing a struct, or accessing a member of an `int`, where the compiler just has no clue how it should do it, it gives up and throws an error. – Daniel Fischer Apr 24 '13 at 21:05

4 Answers4

29

The syntax you are looking for is somewhat cumbersome, but it looks like this:

// Declare test_array_ptr as pointer to array of test_t
test_t (*test_array_ptr)[];

You can then use it like so:

test_array_ptr = &array_t1;
(*test_array_ptr)[0] = new_struct;

To make the syntax easier to understand, you can use a typedef:

// Declare test_array as typedef of "array of test_t"
typedef test_t test_array[];
...
// Declare test_array_ptr as pointer to test_array
test_array *test_array_ptr = &array_t1;
(*test_array_ptr)[0] = new_struct;

The cdecl utility is useful for deciphering complex C declarations, especially when arrays and function pointers get involved.

Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
  • thanks for the helpful answer! but what is the difference from the first answer. where function foo() { test_array_ptr = array_t1; test_t new_struct = {0,0}; test_array_ptr[0] = new_struct; } – user1539348 Apr 24 '13 at 21:09
  • 1
    Please show how to get access to (*test_array_ptr)[1].obj1 but with -> operator. Is it possible? I understand that test_array_ptr[1]->obj1 will give me incorrect result. – Evgeny Sep 12 '19 at 15:25
5

test_t * test_array_ptr is a pointer to test_t. It could be a pointer to single instance of test_t, but it could be a pointer to the first element of an array of instances of test_t:

test_t array1[1024];

test_t *myArray;
myArray= &array1[0];

this makes myArray point to the first element of array1 and pointer arithmetic allows you to treat this pointer as an array as well. Now you could access 2nd element of array1 like this: myArray[1], which is equal to *(myArray + 1).

But from what I understand, what you actually want to do here is to declare a pointer to pointer to test_t that will represent an array of pointers to arrays:

test_t array1[1024];
test_t array2[1024];
test_t array3[1025];

test_t **arrayPtr;
arrayPtr = malloc(3 * sizeof(test_t*));   // array of 3 pointers
arrayPtr[0] = &array1[0];
arrayPtr[1] = &array2[0];
arrayPtr[2] = &array3[0];
LihO
  • 41,190
  • 11
  • 99
  • 167
  • how would i just create a pointer to a single array struct at a time? and how would I access a struct within the array? – user1539348 Apr 24 '13 at 20:47
0

The issue you have is that you are taking (*test_array_pointer) which is the first element of the array. If you want to assign to a specific element of the array, you would do the following...

function foo()
{
    test_array_ptr = array_t1;

    test_t new_struct = {0,0};
    memcpy( &test_array_ptr[0], &new_struct, sizeof( struct test_t ) );
}

if you want to always assign to the first element of the array you could do this...

function foo()
{
    test_array_ptr = array_t1;

    test_t new_struct = {0,0};
    memcpy( test_array_ptr, &new_struct, sizeof( struct test_t ) );
}

and has been pointed out to me by others, and something I honestly had entirely forgotten for having not used it in the better part of forever, you can do direct assignment of simple structures in C...

function foo()
{
    test_array_ptr = array_t1;

    test_t new_struct = {0,0};
    test_array_ptr[0] = new_struct;
}
K Scott Piel
  • 4,320
  • 14
  • 19
0

I would use a pointer to a pointer like:

test_t array_t1[1024];
test_t **ptr;
ptr = array_t1;
ptr[0] = ...;
ptr[1] = ...;
etc.
Sheldon Juncker
  • 587
  • 1
  • 5
  • 18