How to share non-global C data structures
This is my OLD blog. I've copied this post over to my NEW blog at:
http://www.saltycrane.com/blog/2007/02/how-to-share-non-global-c-data/
You should be redirected in 2 seconds.
My goal is to share C data structures without using global variables. I have one function that will fill the data structure and other functions that will use and optionally modify the data. I would also like the data structure definition to be in the same file as the function that fills it. (It looks like this last requirement requires pointers to pointers and a malloc so I will abandon it. See this thread in the comp.lang.c newsgroup.)
My solution is to pass pointers to structures to functions as described here: http://irc.essex.ac.uk/www.iota-six.co.uk/c/h4_structs_part_3.asp Here is my implementation and notes:
main.c:
main.c contains the main function which calls the other functions that operate on the data structure. It also defines (allocates memory) for the data structure at the file level. The data structure is declared using the
static
keyword so that it will have static duration (i.e. it will exist from
program start to finish), but it will have internal linkage
(i.e. it won't be global). (For more information on declarations
see http://www-ccs.ucsd.edu/c/declare.html
The address operator, &
, is used to create a pointer to the
data structure which is passed to the other functions.#include "defs.h" #include "get_data.h" #include "use_data.h" static DATA data; int main() { get_data(&data); modify_data(&data); display_data(&data); return 0; }defs.h:
defs.h contains the combined structure data type declaration and typedef declaration to create the new type name,
DATA
. (See
my notes on struct and typedef.) It is included in all the files that
declare the data structure or a pointer to the data structure.#ifndef DEFS_H_ #define DEFS_H_ typedef struct { int item1; int item2; float item3; float item4; } DATA; #endif /*DEFS_H_*/get_data.c:
get_data.c contains the function to initially fill the data structure. It is passed a pointer to the data structure defined in main.c. It uses the structure pointer operator,
->
, to access the members of the
structure pointed to by data_ptr
. data_ptr
is
the only local variable in this function-- the data structure being filled
is the same one that was defined in main.c.#include "defs.h" int get_data(DATA *data_ptr) { data_ptr->item1 = 1; data_ptr->item2 = 2; data_ptr->item3 = 3.0; data_ptr->item4 = 4.0; return 0; }use_data.c:
use_data.c contains the functions that use and modify the data in the data structure. They are both passed a pointer to the structure similar to get_data.c.
#includeget_data.h#include "defs.h" int modify_data(DATA *data_ptr) { data_ptr->item2 += 1; data_ptr->item4 += 1.0; return 0; } int display_data(DATA *data_ptr) { printf("data.item1: %d\n", data_ptr->item1); printf("data.item2: %d\n", data_ptr->item2); printf("data.item3: %f\n", data_ptr->item3); printf("data.item4: %f\n", data_ptr->item4); return 0; }
get_data.h and use_data.h contain the function declarations (function prototypes) and should be included wherever the functions are used.
#ifndef GET_DATA_H_ #define GET_DATA_H_ int get_data(DATA *data_ptr); #endif /*GET_DATA_H_*/use_data.h
#ifndef USE_DATA_H_ #define USE_DATA_H_ int modify_data(DATA *data_ptr); int display_data(DATA *data_ptr); #endif /*USE_DATA_H_*/Output:
Running the program produces the following output:
data.item1: 1 data.item2: 3 data.item3: 3.000000 data.item4: 5.000000Other notes:
Header files should only contain declarations. They should not contain variable definitions because if the header file is included in multiple locations there would be multiple definitons of the same variable. (See this thread in the comp.lang.c newsgroup.)
Diagram:
Revision 2 based on comments from this thread on the comp.lang.c newsgroup:
Revision 3: Updated based on more comments from the newsgroup. Also, I think my original #includes were OK.
No comments:
Post a Comment