Re: Passing an array of structuresfrom a pointer?
- From: "Giovanni Dicanio" <giovanniDOTdicanio@xxxxxxxxxxxxxxxxx>
- Date: Mon, 29 Sep 2008 23:25:38 +0200
There are several things that should be fixed in your code...
I've tried an attempt to do that, and I tried to "clean" the header and main ..c file.
I post the reviewed files here, with some comments of mine identified by @@
It compiles fine on Visual C++...
<code file="Main.h">
/*
* Main.h
*/
/* @@ Guard to avoid multiple inclusions */
#ifndef MAIN_H_INCLUDED
#define MAIN_H_INCLUDED
struct ddlbColl1{
long LINK_ID;
int LIST_NUMBER;
};
/* @@ Separate structure type definition from structure instantiation */
/* @@ Use g_ prefix to identify global variables, this avoid bad naming conflicts */
/* @@ This is defined in some .c file */
extern struct ddlbColl1 g_DDLB_COLL1[];
typedef struct ddListBox{
int x;
long y;
/* long *xxx; //<<< Pointer that holds the address of the DDLB_COLL1[] array! */
/* @@ so make it struct ddlbColl1 pointer type, not long */
struct ddlbColl1 * xxx;
} DDLB; // Eventually Will be defined in a function in .c file.
/* @@ This is defined in some .c file */
extern DDLB * g_obj_DDLB; // Eventually Will be defined in a function in .c file.
/* @@ Function prototypes */
DDLB* ULC_DDLB_config_ddlb (struct ddlbColl1 DDLB_COLL1[], int x, int y);
void ULC_DDLB_ddlb (DDLB *obj_DDLB);
#endif /* MAIN_H_INCLUDED */
</code>
<code file="Main.c">
/*
* Main.c
*/
#include "Main.h"
#include <stdlib.h>
/*
* Definitions of global variables
*/
struct ddlbColl1 g_DDLB_COLL1[] =
{
200, 4,
201, 8
};
DDLB * g_obj_DDLB = NULL; /* @@ will be assigned later */
/*
* Function Implementations
*/
DDLB* ULC_DDLB_config_ddlb
( struct ddlbColl1 DDLB_COLL1[], int x, int y)
{
g_obj_DDLB = NULL;
g_obj_DDLB = (DDLB*) malloc (sizeof (struct ddListBox));
g_obj_DDLB->x = x;
g_obj_DDLB->y = y;
g_obj_DDLB->xxx = DDLB_COLL1; //Assigning the address of the DDLB_COLL1[] array!
return g_obj_DDLB;
}
void ULC_DDLB_ddlb ( DDLB *obj_DDLB )
{
// implementation file which uses the infos from DDLB_COLL1 array!
if(obj_DDLB->xxx[0].LINK_ID == 200)
{ //then do code!
}
}
int main()
{
g_obj_DDLB = ULC_DDLB_config_ddlb( g_DDLB_COLL1, 10,5 );
ULC_DDLB_ddlb (g_obj_DDLB);
return 0;
}
</code>
HTH,
Giovanni
-----------------------------------------
"Robby" <Robby@xxxxxxxxxxxxxxxxxxxxxxxxx> ha scritto nel messaggio news:C38C4AA4-CC5F-413F-A72A-1B7E0363C0C1@xxxxxxxxxxxxxxxx
Hello Barry,
I just tried to access data from the DDLB_COLL1 array and got an error!
here is the code I am using:
====================================Main Header
struct ddlbColl1{
long LINK_ID;
int LIST_NUMBER;
} DDLB_COLL1[] = // Eventually Will be defined in a function in .c
file.
{
200, 4,
201, 8};
typedef struct ddListBox{
int x;
long y;
long *xxx; //<<< Pointer that holds the address of the DDLB_COLL1[] array!
} DDLB; // Eventually Will be defined in a function in .c file.
DDLB *obj_DDLB; // Eventually Will be defined in a function in .c file.
DDLB* ULC_DDLB_config_ddlb (struct ddlbColl1 DDLB_COLL1[], int x, int y);
void ULC_DDLB_ddlb ( DDLB *obj_DDLB);
=============================================
=========================================Main
int main()
{
obj_DDLB = ULC_DDLB_config_ddlb ( DDLB_COLL1, 10,5);
ULC_DDLB_ddlb (obj_DDLB);
return 0;
}
DDLB* ULC_DDLB_config_ddlb
( struct ddlbColl1 DDLB_COLL1[], int x, int y)
{
obj_DDLB = NULL;
obj_DDLB = (DDLB*) malloc (sizeof (struct ddListBox));
obj_DDLB->x = x;
obj_DDLB->y = y;
obj_DDLB->xxx = DDLB_COLL1; //Assigning the address of the DDLB_COLL1[] array!
return obj_DDLB;
}
void ULC_DDLB_ddlb ( DDLB *obj_DDLB)
{
// implementation file which uses the infos from DDLB_COLL1 array!
if(obj_DDLB->xxx[0].LINK_ID == 200)
{ //then do code!}
}
==========================================
I am trying to access the LINK_ID data from the first structure in the
DDLB_COLL1 array! This doesn't reference 200? cause I am getting a "Expecting
a structure/union" error????
long x;
x=obj_DDLB->xxx[0].LINK_ID
However I tried
long x;
x = obj_DDLB[0].LINK_ID;
It does compile without errors, however I don't think this would return 200
? I mean how could it, I didn't bother to run it on my processor. obj_DDLB is
a pointer of type DDLB which one of its members hold the address (xxx) to
the DDLB_COLL1 array???? Am interpreting this right? If so, then how can it
return 200?
oooofff! confused!
Roberto
---------------------------------------------------------------------------------------------
"Robby" wrote:
Hello Barry,
I really must thankyou for your much valued feedback. Now I see the reason
why we should only declare stuff in headers and only define stuff in .c
files. Thankyou for pointing it out with great scrutny.
Too often I have been so caught up in just getting the project to work at
all costs and without debuging errors which rendered me sort of absent minded
about specific details that contribute in doing things the right way! And for
this I appolagize to you and the newsgroups.
It makes sence, to only declare structs in headers and then define the
arrays, variables or pointers of that struct within functions that require
the use of the that structure! In my example, the struct should be declared
in the header and the array of that struct should be defined in the
function. Also, this seems to suit me fine since my MCU will use its memory
more efficiently as opposed to leaving all my structures global.
However, what if you have a simple array like this:
int xxx[5] = {1, 3, 5, 7, 9};
In the header we would declare?
int xxx[5];
and in the .c file we define?
int xxx[0] = 1;
int xxx[0] = 3;
int xxx[0] = 5;
int xxx[0] = 7;
int xxx[0] = 9;
What is the right way? Its nice to just declare and define it in the haeder
all in one line, but if you say its a nono! then is the above correct?
I re-wrote my example code the best I could so that it compiles.
However, for now there is too much to change to my code if I would define
the array of structures in a functions as opposed to defining it globally.
Just to mention this, I did try to re-code my file using your reccomendation
of defining the array of struct in a function of .c file, but another
function gave me an undefined identifier error in one of my other functions
more precicely at a for loop:
for(i=0; i<DDLB_ITEM_LIST1; i++)
{ ... other code... }
where DDLB_ITEM_LIST1 is a global macro:
#define DDLB_ITEM_LIST1 (long) ((sizeof (DDLB_COLL1)/sizeof (struct
ddlbColl1)))
It will take me some time before I can modify my file to fully implement the
declations and defines appropriately.
Any how the following compiles without errors!
====================================Main Header
struct ddlbColl1{
long LINK_ID;
int LIST_NUMBER;
} DDLB_COLL1[] = // Eventually Will be defined in a function in .c
file.
{
200, 4,
201, 8};
typedef struct ddListBox{
int x;
long y;
long *xxx;
} DDLB; // Eventually Will be defined in a function in .c file.
DDLB *obj_DDLB; // Eventually Will be defined in a function in .c file.
DDLB* ULC_DDLB_config_ddlb (struct ddlbColl1 DDLB_COLL1[], int x, int y);
void ULC_DDLB_ddlb ( DDLB *obj_DDLB);
=============================================
=========================================Main
int main()
{
obj_DDLB = ULC_DDLB_config_ddlb (e_CREATE, e_I500, DDLB_COLL1,
pMN_DC->CURR_MENU_ITEM);
ULC_DDLB_ddlb (obj_DDLB);
return 0;
}
DDLB* ULC_DDLB_config_ddlb
( struct ddlbColl1 DDLB_COLL1[], int x, int y)
{
obj_DDLB = NULL;
obj_DDLB = (DDLB*) malloc (sizeof (struct ddListBox));
obj_DDLB->x = x;
obj_DDLB->y = y;
obj_DDLB->xxx = DDLB_COLL1;
return obj_DDLB;
}
void ULC_DDLB_ddlb ( DDLB *obj_DDLB)
{
// implementation file which uses the infos from DDLB_COLL1 array!
}
==========================================
>>the "ddlbColl1" structure will have an array of itself declared as
>>"DDLB_COLL1". In my example below I only declared one (1) such strucure
>>called "ddlbColl1", but someday I could end up having 2, 3 or even 5 of >>them!
>I'm sorry but this makes no sense. A structure may not contain
>itself. The significance of the case change is not apparent.
I appolagize Barry!
"I will declare a struct called "ddlbColl1" and then define an array of
"ddlbColl1" structures...."
>Do not define objects in your header. However, do declare obj_DDLB as
>an external pointer with
>extern DDLB *obj_DDLB;
>so that when you define it in a source file other source files will
>have access to it. (Ignoring the issue of whether a global pointer is
>a good idea or not.)
I will have to work on this!
>>{
>>200, 4,
>>201, 8};
>>
>>DDLB* ULC_DDLB_config_ddlb
>Surely this function definition is not in a header but in a separate
>source file.
Yes it is, I just put it there so I can show my sample code in one page!
>Since you don't need obj_DDLB to be global, you should define it here.
>You will end up with three objects with that name, one each in main,
>ULC_DDLB_config_ddlb, and ULC_DDLB_ddlb. Since they all have
>different scope, there is no problem, However, to avoid confusion, you
>might want to give the object in each function a slightly different
>name
For now, I prefer to just keep the obj_DDLB object global. When I
re-structure the code according to your reccomendations, I will define it as
you say. However when I do this I will most probably use a new post since I
will undoubfully have problems!
The above code has been adapted to the full blown project and now compiles
without errors. If I have problems accessing the informations in the
DDLB_COLL1[] array while in the "void ULC_DDLB_ddlb ( DDLB *obj_DDLB)"
function, I will certainly get back to the newsgroups, under a new post
though!
Barry, I thankyou for your sincere help!
--
Best regards
Roberto
--
Best regards
Robert
"Barry Schwarz" wrote:
> On Sun, 28 Sep 2008 15:51:00 -0700, Robby
> <Robby@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote:
>
> >Hello,
> >
> >I have a two part question. I do understand the principle of an array > >like so:
> >
> >int xxx[10];
> >
> >where xxx holds the address of the first item. But, when using this > >analogy
>
> First problem: xxx does not hold the address of the first item. In
> many (but not all) contexts, the expression xxx is ***converted*** to
> the address of the first item, equivalent to the expression &xxx[0].
>
> >with arrays of structures, I feel a little unsure! Anyways, here is my
> >problem!
> >
> >-[Q#1]-
> >I am trying to pass the address of an array of structures, that have > >already
> >been declared in one of my headers. I don't know... but I feel like I > >am
>
> It is extremely undesirable that an array of struct be defined in a
> header. Headers contain typedef definitions, external declarations,
> function prototypes, and macro definitions but hardly ever object
> definitions.
>
> >drawing a blank ! I know I did similar stuff like this but not from > >the same
> >exact perspective and the fact that I need to pass the address of an > >array of
> >strucutes somehow confuses me! Basically I need to pass the address of > >the
> >array of structures to a fiunction that will then store this address > >in
> >another structure for later use.
>
> There is no difference in passing an array of struct to a function
> than in passing any other array (do you use strcpy or sprintf or
> sscanf). Arrays are passed by value and the actual value used is the
> address of the first element of the array.
>
> If you have a declaration of the form
> struct x{...};
> and an array definition of the form
> struct x y[N];
> and a function that expects such an array (that is the function
> prototype specifies either
> void func(struct x []...);
> or
> void func(struct x *...);
> which are equivalent as noted in my first comment and where the return
> type and other parameters are not part of this discussion), then you
> pass the array of struct to the function with
> func(y ...);
>
> >
> >Here's what I am trying to accomplish! In a header file I will be > >declaring
> >several strucutures that have several members. Furthermore, an array > >for
> >every one of these structures will be declared. For example, as shown > >below,
>
> Don't define arrays in headers. How will you avoid the duplicate
> definition problem if your code has more than once source file? Arrays
> should be defined in the primary function that uses them and passed to
> any secondary functions as arguments. If you absolutely must have
> global arrays, declare them as external in the header and define them
> in the same source file as main.
>
> >the "ddlbColl1" structure will have an array of itself declared as
> >"DDLB_COLL1". In my example below I only declared one (1) such > >strucure
> >called "ddlbColl1", but someday I could end up having 2, 3 or even 5 > >of them!
>
> I'm sorry but this makes no sense. A structure may not contain
> itself. The significance of the case change is not apparent.
>
> >
> >The thing is, that in my main calling function I want to configure all > >the
> >necessary components for my drop down list box by calling the
> >ULC_DDLB_config_ddlb ( ) function which will setup informations in the
> >"ddListBox" structure . One of the parameters of this function will be > >the
> >desired array of strucutres collections such as the DDLB_ARY[] !
> >
> >Then once back in main I would call the:
> >
> >ULC_DDLB_ddlb (obj_DDLB);
> >
> >function and pass the pointer to a ddListBox structure and manipulate > >its
> >data, such as the data from the DDLB_COLL1 array within the function's
> >implementation code.
> >
> >-[Q#2]-
> >When I am in the void ULC_DDLB_ddlb () function, will I be able to > >reference
> >data from the DDLB_COLL1 array? I believe that to retreive or modify > >the data
> >in the DDLB_COLL1 array I can do it like this: right?
> >
> >DDLB_COLL1[1]. LIST_NUMBER;
> >
> >I could be wrong, this is the first time I am passing arrays around > >this
> >way!!!!
> >
> >Here's the code sample, I really am unsure of the lines flagged with > >"[***]"
> >!!!
> >All help is appreciated!
> >
> >==============================================
> >
> >typedef struct ddListBox{
> >int x;
> >long y;
> >struct ddlbColl1 DDLB_ARY[]; //Store address of DDLB_COLL1 here ! > >[***]
>
> If you want to store an address here, use a pointer, not an array.
>
> >} DDLB;
> >DDLB *obj_DDLB;
>
> Do not define objects in your header. However, do declare obj_DDLB as
> an external pointer with
> extern DDLB *obj_DDLB;
> so that when you define it in a source file other source files will
.
- Follow-Ups:
- References:
- Passing an array of structuresfrom a pointer?
- From: Robby
- Re: Passing an array of structuresfrom a pointer?
- From: Barry Schwarz
- Re: Passing an array of structuresfrom a pointer?
- From: Robby
- Re: Passing an array of structuresfrom a pointer?
- From: Robby
- Passing an array of structuresfrom a pointer?
- Prev by Date: Re: Passing an array of structuresfrom a pointer?
- Next by Date: Re: Passing an array of structuresfrom a pointer?
- Previous by thread: Re: Passing an array of structuresfrom a pointer?
- Next by thread: Re: Passing an array of structuresfrom a pointer?
- Index(es):
Relevant Pages
|