On 10 Aug 2006 16:16:04 -0700,
wrote:
>I am having trouble figuring out how to declare a pointer to an array
>of structures and initializing the pointer with a value. I've looked
Clarify your terminology. The phrase pointer to an array is
frequently misused to mean pointer to the first element of the array.
For a type T, this would be coded as T *ptr. To be technically
correct, a pointer to an array of type T would be coded as T (*ptr)[N]
where N would be a self-defining value (compile time constant). Which
do you really want?
Your following code deals with the second type. However, since the
first type allows you to step through the array more easily (less
typing), the second type is much less frequently used.
>at older posts in this group, and tried a solution that looked
>sensible, but it didn't work right. Here is a simple example of what
>I'm trying to accomplish:
>
>// I have a hardware peripheral that I'm trying to access
>// that has two ports. Each port has 10 sequential
>// registers. Create a structure definition that
>// defines a single port.
>
>typedef struct {
> long long1;
> long long2;
> long long3;
> long long4;
> long long5;
> long long6;
> long long7;
> long long8;
> long long9;
> long long10;
>} volatile my_struct;
Doesn't the volatile need to be between the words typedef and struct
on the first line of the declaration?
>
>// Create a pointer to an array of two structures
>my_struct (*my_struct_ptr)[2];
This does define a pointer to an array of 2 struct.
>
>#define PERIPHERAL_BASEADDR 0xA0000000
>
>int main(int argc, char **argv)
>{
> // This is the syntax I came up with to initialize
> // the pointer. Keep in mind that this line of code
> // isn't even needed in this example to illustrate the
> // behavior of the compiler with respect to addressing.
> my_struct_ptr = (my_struct (*)[])PERIPHERAL_BASEADDR;
If you change the subscript from [] to [2] it should be syntactically
correct.
>
> printf("&my_struct_ptr[0] = %08X\n",
> &my_struct_ptr[0]);
Here you promise the argument corresponding to %X will have type int.
You actually pass the an argument that has type pointer to array of 2
struct. (The & and the [0] basically cancel each other.) This
invokes undefined behavior. If you want to print the value of a
pointer, use %p and cast the value to a void*.
>
> printf("&my_struct_ptr[1] = %08X\n",
> &my_struct_ptr[1]);
>
> printf("sizeof(my_struct) = %x\n",
> sizeof(my_struct));
sizeof evaluates to a size_t which need not be an int. Cast it if you
want to use %x.
>
> printf("sizeof(my_struct_ptr[0]) = %x\n",
> sizeof(my_struct_ptr[0]));
>
> printf("sizeof(my_struct_ptr[1]) = %x\n",
> sizeof(my_struct_ptr[1]));
>
> printf("&(my_struct_ptr[0]->long1) = %08X\n",
> &(my_struct_ptr[0]->long1));
>
> printf("&(my_struct_ptr[0]->long10) = %08X\n",
> &(my_struct_ptr[0]->long10));
>
> printf("&(my_struct_ptr[1]->long1) = %08X\n",
> &(my_struct_ptr[1]->long1));
>
> printf("&(my_struct_ptr[1]->long10) = %08X\n",
> &(my_struct_ptr[1]->long10));
>}
>
>Here is the output of the program:
>
>&my_struct_ptr[0] = A0000000
>&my_struct_ptr[1] = A0000050
>sizeof(my_struct) = 28
>sizeof(my_struct_ptr[0]) = 50
>sizeof(my_struct_ptr[1]) = 50
>&(my_struct_ptr[0]->long1) = A0000000
>&(my_struct_ptr[0]->long10) = A0000024
>&(my_struct_ptr[1]->long1) = A0000050
>&(my_struct_ptr[1]->long10) = A0000074
>
>It correctly calculates the size of the typedef'd structure, but it
>reports the size of each element of the array as twice as big as it
No it doesn't. my_struct has a size of 40 bytes (hex 2

.
my_struct_ptr is a pointer to an array of 2 struct. my_struct_ptr[0]
is the array it points to. Since the array has two elements, the size
of the array is 80 bytes (hex 50). Hence the question I asked at the
beginning. You want the pointer to point to an element of the array,
not the array itself.
>should be. If there are three elements in the array, then the size of
>each element is 3 times as big. In this example, long1 of the second
You never asked for the size of an element of the array. To do so you
would have to code my_struct_ptr[0][0].
>element should be at address A0000028.
It is. You never asked for the address of that variable. The name
for that variable is my_struct_ptr[0][1].long1. Put an & in front to
get its address.
Your code - &(my_struct_ptr[1]->long1) - evaluates as follows:
my_struct_ptr is a pointer to an array of struct
my_struct_ptr[1] is the second array it points (the next array
past the first)
my_struct_ptr[1] is an array expression. As usual (when not the
operand of sizeof or &), the array expression evaluates to the address
of the first element of the array with type pointer to element. Since
the array is an array of struct, this evaluates to the address of the
first struct of the second array or &my_struct_ptr[1][0] with type
pointer to struct.
my_struct_ptr[1]->long1 is the first element of this struct which
is actually the third struct starting at your special address. The
first struct is my_struct_ptr[0][0], the second is [0][1], and [1][0]
is the third.
>
>I am using the GCC compiler, but I don't think it is a bug in the
>compiler. I tried it in Visual C++ and got the same results.
The "problem" is you chose to use a pointer to array rather than
pointer to first element of array.
>
>I tried to use a pointer to a single structure and use it like an
>array. That only half works because the compiler doesn't see it as an
>array of structures and therefore you can't access the elements of the
>structure and index as well.
Yes it can. Show your code so we can see what you did wrong.
Remove del for email