Project Home
Project Home
Trackers
Trackers
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - C syntax with a struct array: (9 Items)
   
C syntax with a struct array  
Hi

I define such a array of struct

typedef struct
{
    Uint8 bloc;
    Uint8 champ;
    Uint32 data;
}CommandeCVS;

typedef CommandeCVS CommandesCVS[MAXLIGNECSV];

I use it in such function
Uint32 lectureCVS(Char * nomFichier, CommandesCVS * commandesCVS)
{
   ....
     commandesCVS[ctLigne]->bloc = atoi(pch);
    ....
}

I was very surprised when i discover that such instruction has wrong memory access
the memory is writed out of the array of struct even if ctLigne is far from the max

Instead i wrote (*commandesCVS)[ctLigne].bloc = atoi(pch);

And it work!

Am i wrong with the first syntax or it is a compiler bug?

Thank

Olivier


RE: C syntax with a struct array  
I think you meant

Uint32 lectureCVS(Char * nomFichier, CommandesCVS * commandesCVS) {
   ....
     commandesCVS[ctLigne].bloc = atoi(pch);
    ....
}

Not 
Uint32 lectureCVS(Char * nomFichier, CommandesCVS * commandesCVS) {
   ....
     commandesCVS[ctLigne]->bloc = atoi(pch);
    ....
}

-----Original Message-----
From: Gervot Olivier [mailto:community-noreply@qnx.com] 
Sent: Dienstag, 16. Juli 2013 14:54
To: general-ide
Subject: C syntax with a struct array

Hi

I define such a array of struct

typedef struct
{
    Uint8 bloc;
    Uint8 champ;
    Uint32 data;
}CommandeCVS;

typedef CommandeCVS CommandesCVS[MAXLIGNECSV];

I use it in such function
Uint32 lectureCVS(Char * nomFichier, CommandesCVS * commandesCVS) {
   ....
     commandesCVS[ctLigne]->bloc = atoi(pch);
    ....
}

I was very surprised when i discover that such instruction has wrong memory access the memory is writed out of the array
 of struct even if ctLigne is far from the max

Instead i wrote (*commandesCVS)[ctLigne].bloc = atoi(pch);

And it work!

Am i wrong with the first syntax or it is a compiler bug?

Thank

Olivier






_______________________________________________

General
http://community.qnx.com/sf/go/post103214
To cancel your subscription to this discussion, please e-mail general-ide-unsubscribe@community.qnx.com
Re: RE: C syntax with a struct array  
It was really 
 commandesCVS[ctLigne]->bloc = atoi(pch);

commandesCVS[ctLigne].bloc = atoi(pch);
Doesn't compile

Olivier 
RE: RE: C syntax with a struct array  
You shouldn't write code like this it's too hard to read, maintain.

You are passing a poiner to the array pointer for some reason and then trying to use that as an array pointer. 

you need to dereference the pointer to get the array,  i.e. what you need above is 
     (*commandesCVS)[ctLigne].bloc = atoi(pch);


Or just loose the * in the arg. 
Uint32 lectureCVS(Char * nomFichier, CommandesCVS commandesCVS)

commandesCVS is already a pointer.


-----Original Message-----
From: Gervot Olivier [mailto:community-noreply@qnx.com] 
Sent: Dienstag, 16. Juli 2013 15:13
To: general-ide
Subject: Re: RE: C syntax with a struct array

It was really 
 commandesCVS[ctLigne]->bloc = atoi(pch);

commandesCVS[ctLigne].bloc = atoi(pch);
Doesn't compile

Olivier 



_______________________________________________

General
http://community.qnx.com/sf/go/post103216
To cancel your subscription to this discussion, please e-mail general-ide-unsubscribe@community.qnx.com
Re: RE: RE: C syntax with a struct array  
It works
I forgot that commandesCVS is already a pointer.

Thanks

Olivier
Re: C syntax with a struct array  
your structure is going to get you into trouble ... which is what I am suspecting to be the cause of all your troubles.

you declared 2 Uint8, followed by an Uint32, which will then put the Uint32 on an address boundary that is not 32-bit 
aligned. So unless the compiler will automatically insert 2 bytes between your two Uint8 elements and your Uint32 
element, you will get a processor address exception error.

as a general rule, never ever design data structures that has 32-bit elements that are not on a 32-bit address boundary,
 and likewise for 16 and 64-bit elements.

you need to add a dummy Uint16 element after the second Uin8 element in your structure.
Re: C syntax with a struct array  
I confirm there is an alignment problem.
But it si not the origin of the problem. There is only 8 bytes unused.
It was a pointer problem
Re: C syntax with a struct array  
I mean 2 bytes unused
Re: C syntax with a struct array  
Okay, I was pre-occupied with your word alignment issue ... now looking at your declarations ... I see it now, this is 
something that I have encountered before.

When you create an array of data structures, the variable becomes a pointer to the first element of the array, or a 
pointer to the first CommandeCVS structure in a sequence of MAXLIGNECVS structures.

When pass it in as "CommandesCVS * commandesCVS", commandesCVS is now a pointer to an array of data structures. which is
 a pointer to a pointer of the structure.

So when you perform commandesCVS[ctLigne]->X, you are starting with the pointer to the pointer, and then offsetting it 
by ctLigne * sizeof (CommandeCVS), which will now point to somewhere weird.

You need to dereference the "pointer to the pointer" back to just the pointer, which is why when you perform (*
commandesCVS)[ctLigne].X, it works. The (*commandesCVS) will perform the dereferencing, and you are now back to the 
structure array.

You really do not need to pass in "CommandesCVS * commandesCVS", you can pass in "CommandesCVS commandesCVS", since it 
is a pointer already. You only need the former type of declaration if you have multiple CommandesCVS, and lectureCVS 
will reassign *commandesCVS to point to a different CommandesCVS.

I recommend that you change it to:
Uint32 lectureCVS (Char * nomFichier, CommandesCVS commandesCVS)

Then, you will use commandesCVS[ctLigne].X = blah;

However, I seriously recommend you change your data structure. Using what you have right now, if you were to do:
commandesCVS[1].data = blah;
you will be writing a 32-bit word into (base_addr + 0x6), which you cannot do; the processor will throw an address 
exception error, and your process will get kicked out by the kernel, and you will get a core dump (if dumper is running)
.

hope this helps!!
- Ed