In C: How to set a pointer to a member of a structure that is an array?

How can I write my own code, for example, the specific index of the array array that is part of the structure? The following code gives me problems.

// main.c void clean_buffers(void); // prototype struct DEV_STATUS { unsigned char ADDR; unsigned char DEV_HAS_DATA; unsigned char ETH_HAS_DATA; unsigned char DATA[20]; }; struct DEV_STATUS g_cmdQueue[60] = {0}; void main(void) { clean_buffers(); while (1) { ;// MCU tasks } } void clean_buffers(void) { unsigned char theCount = 0; byte queIdx; for (queIdx = 0; queIdx < 59; queIdx++) { struct DEV_STATUS *p_struct; unsigned char *p_data; p_struct = &g_cmdQueue[queIdx]; p_data = &p_struct->DATA; p_struct->ADDR = 0; p_struct->DEV_HAS_DATA = 0; p_struct->ETH_HAS_DATA = 0; theCount = 0; while(*(p_data+theCount) != 0) { *(p_data+(theCount++)) = 0; } } } // EOF main.c 

I get a compiler error "struct / union member expected" in the following line:

 p_data = &p_struct->DATA; 

How to write a pointer if I have to access, for example, a specific value of a DATA structure element [3]? I am confused, I thought like p_data = & p_struct-> DATA; determined, I should be able to get it with * (pdata + 3), but I think I missed something.

+6
c pointers dereference member structure
source share
5 answers

Are you sure you are compiling the same code that you posted here?

If your compiler complains about this line

 p_data = &p_struct->DATA; 

with the message "struct / union expected", your compiler is probably broken.

Note that &p_struct->DATA is a perfectly valid expression in C. There are absolutely no problems with this expression in itself.

The problem here is that this is not what you need in your case. &p_struct->DATA returns a pointer to the entire array of "DATA", i.e. pointer of type unsigned char (*)[20] . You are trying to assign this value to an unsigned char * pointer. This is illegal in C because the types are completely different, but traditionally C compilers answered it with a simple warning about type mismatch and performed an implicit conversion (which, BTW, means that your source code, although dirty, should still work on destination).

Even if some compiler decides to flag this mismatch as an error (this is normal), it still should not complain about any problems of the "expected type of structure / union". There are no such problems.

PS As already mentioned, you really need p_data = &p_struct->DATA[0] , but this still does not explain the strange behavior of your compiler. Could it be that "DATA" is a macro defined somewhere before the definition of "clean_buffers"?

Added 10/19/2009: Nate, in your code you will access your array using theCount index. Since you are still using index access, there is no reason to even create the index that you are trying to create. The code will work fine without any additional pointer, just touch the DATA field

 theCount = 0; while (p_struct->DATA[theCount] != 0) { p_struct->DATA[theCount++] = 0; 

(I would probably use a for loop here).

If you really insist on creating this pointer and still use index access, the code should look something like this (others have already suggested this several times)

 p_data = p_struct->DATA; /* or &p_struct->DATA[0] */ ... theCount = 0; while (p_data[theCount] != 0) { p_data[theCount++] = 0; 

In addition, you can choose a more "exotic" option :)

 unsigned char (*p_data)[20]; /* <- note: declared differently */ ... p_data = &p_struct->DATA; /* <- note: your original version */ ... theCount = 0; while ((*p_data)[theCount] != 0) { (*p_data)[theCount++] = 0; 

However, returning to the unsigned char *p_data , since you are creating this pointer, it might be wiser to use the "moving pointer" technique instead of using index access

 unsigned char *p_data; ... p_data = p_struct->DATA; /* or &p_struct->DATA[0] */ ... while (*p_data != 0) { *p_data++ = 0; 

As always, it all depends on personal preferences. Of course, none of this will work until you get rid of this macro noise.

+8
source share

Lose and p_data = &p_struct->DATA;

p_struct is already a pointer. Then use p_data [] to access your array.

+3
source share

What you should write is one of two things:

 p_data = p_struct->DATA; // DATA is the address of the first element. 

OR

 p_data = &p_struct->DATA[0]; // taking the address of the first element. 
+2
source share

Just delete and at the beginning, for example:

 p_data = p_struct->DATA; 

This is special syntax for arrays (remember that they are always passed as a reference), and this is equivalent:

 p_data = &p_struct->DATA[0]; 

And yes, now you can use * (pdata + 3)

Hope this helps.

+1
source share

Oops! Thanks AndreyT

<y> struct DEV_STATUS * p_struct; unsigned char * p_data; p_struct = & g_cmdQueue [queIdx]; p_data = & p_struct-> DATA;

p_struct is a pointer to struct DEV_STATUS .
&p_struct is the address of a pointer to struct DEV_STATUS (or a pointer to a pointer to struct DEV_STATUS ).

You probably want to change this line to

  p_data = p_struct->DATA; 

Oh ... your clean_buffers() function does not "clear" the g_cmdQueue[59] element.

And since it is a global object, the g_cmdQueue array g_cmdQueue initialized with all zeros even before the first main() statement is executed by exceutes.

-one
source share

All Articles