Advertisement
MBJ

Structs, Heap, and function pointers

MBJ
Jun 26th, 2020
2,022
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.40 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdint.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5.  
  6.  
  7. #define BUF_LEN 20 // for now, maybe will try something different later
  8. #define MAX_PPL 100
  9.  
  10. /******************************************************************************************************************
  11. Developer:  My Name
  12.  
  13. Goal:       Learning about the following:
  14.             - Structures, and typedefing
  15.             - Function pointer members
  16.             - Memory allocation
  17.  
  18. Summary of code:
  19.     I am creating a database of people to keep track of. There is a structure (type data_header) that manages
  20.         a database of a maximum of 100 people (data_header->people_list[MAX_PPL]).
  21.             - note for now, there is a maximum amount and it is not a dynamically allocated value.
  22.     Architecture of structures:
  23.         - data_header
  24.             +- people currently tracking ('used')
  25.             +- people_list[MAX_PPL]
  26.             |   +- list of pointers that point to person_t type structures
  27.             |   +- person:
  28.             |       +- Age
  29.             |       +- Height structure pointer:
  30.             |       |   +- feet
  31.             |       |   +- inches
  32.             |       +- name
  33.             |       +- hair_color
  34.             |       +- eye_color
  35.             +- Function handles for debugging/querying purposes
  36.    
  37.     There are several data structure initialization routines. They each return a pointer to the beginning of the
  38.         storage allocated in memory for the structures. These pointers stay valid, as malloc is not concerned
  39.         with scoping.
  40. ******************************************************************************************************************/
  41.  
  42. typedef struct height_t{
  43.     uint8_t feet;
  44.     uint8_t inches;
  45. }height;
  46.  
  47. typedef struct person_t{
  48.     uint8_t Age;
  49.     height *Height;
  50.     char name[BUF_LEN];
  51.     char hair_color[BUF_LEN];
  52.     char eye_color[BUF_LEN];
  53. }person;
  54.  
  55. /* data_header manages the structures.
  56.     list head
  57.     list tail
  58.     number of items
  59.     base address of an array
  60.     etc...
  61.     What's the purpose of 'static' members in a struct?
  62.    
  63.     Typically for an array: base address, number of items allocated, number used so far, sizeof struct,
  64.                         address of compare routine (for bsearch and qsort),
  65.                         maybe address of a debug print function for elements
  66. */
  67.  
  68. typedef struct data_header_t{
  69.     uint8_t used;
  70.     //ssize_t struct_size;
  71.     person * people_list[MAX_PPL];
  72.     // function addresses
  73.     void (*debug_all)(struct data_header_t *);
  74.     void (*debug_person)(person *);
  75.     uint8_t (*query_person)(struct data_header_t *, char *);
  76. }data_header;
  77.  
  78. void debug_all(data_header * database){
  79.     // say how many people there are,
  80.     // list all of their names
  81.     printf("People keeping track of:\t%d\n",database->used);
  82.     int i;
  83.     printf("List of names:\n");
  84.     for(i = 0; i < database->used; i++){
  85.         printf("%s\n",database->people_list[i]->name);
  86.     }
  87.     return;
  88. }
  89.  
  90. void debug_person(person * JohnyBoi){
  91.     printf("Name:\t\t%s\n",JohnyBoi->name);
  92.     printf("Age:\t\t%d\n",JohnyBoi->Age);
  93.     printf("Height:\t\t%d\'%d\"\n",JohnyBoi->Height->feet,JohnyBoi->Height->inches);
  94.     printf("Hair color:\t%s\n",JohnyBoi->hair_color);
  95.     printf("Eye color:\t%s\n",JohnyBoi->eye_color);
  96.     return;
  97. }
  98.  
  99. uint8_t query_person(data_header * database, char * query){
  100.     uint8_t i;
  101.     for(i=0;i<database->used;i++){
  102.         if(strcmp(database->people_list[i]->name,query) == 0)
  103.             return(i);
  104.     }
  105.     return(-1);
  106. }
  107.  
  108.  
  109.  
  110. // Let's say I want to be able to store 100 people in my database. Need to allocate the space for 100 people structures
  111.  
  112. height * height_init(uint8_t feet, uint8_t inches){ // returns a pointer for a height structure
  113.     height *p = (height*)malloc(sizeof(height));
  114.     p->feet = feet;
  115.     p->inches = inches;
  116.     return p;
  117. }
  118.  
  119. person * person_init(char* name, char* hair_color, char* eye_color, uint8_t age, uint8_t feet, uint8_t inches){ // returns a pointer for a person structure
  120.     person *p = (person*)malloc(sizeof(person));
  121.     p->Age = age;
  122.     p->Height = height_init(feet,inches);
  123.     memcpy(p->name,name,strlen(name)+1);
  124.     memcpy(p->hair_color,hair_color,strlen(hair_color)+1);
  125.     memcpy(p->eye_color,eye_color,strlen(eye_color)+1);
  126.     return p;
  127. }
  128.  
  129. data_header * data_header_init(){
  130.     // need to allocate the space for 100 person structures
  131.     // each person structure also needs to allocate the space for itself + Height (since it's a pointer!)
  132.     data_header *p = (data_header*)malloc(sizeof(data_header)); // note: right now since it won't be dynamic, there is already allocated buffer for max people.
  133.     // that means we have already allocated the space for storing the pointers.
  134.     // if we want to actually use those pointers, we need to allocate the space for the structures they can point at
  135.     p->debug_all = debug_all;
  136.     p->debug_person = debug_person; // returns the function handle/pointer to the member p->debug_person
  137.     p->query_person = query_person;
  138.     return p;
  139. }
  140.  
  141. // include the input for: name, age, height, hair_color, eye_color
  142. int8_t add_person(data_header * database, char *name, char *hair_color, char *eye_color, uint8_t age, uint8_t feet, uint8_t inches){ // need to
  143.     if(database->used == 100)
  144.         return(-1);
  145.     database->people_list[database->used++] = person_init(name,hair_color,eye_color,age,feet,inches);
  146.     return(0);
  147. }
  148.  
  149. void deallocate_data_header(data_header * database){
  150.     // first, need to go thru all of the used structures to deallocate them, then can deallocate the entire thing
  151.     int i;
  152.     for(i=0;i<database->used;i++){
  153.         // deallocating a person:
  154.             // - deallocate height structure
  155.             // - deallocate person structure
  156.         free(database->people_list[i]->Height);
  157.         free(database->people_list[i]);
  158.     }
  159.     // have deallocated every person in the database
  160.     free(database);
  161.     return;
  162. }
  163.  
  164. int main(){
  165.     data_header * My_Database = data_header_init();
  166.     // create Johnny: brown hair, blue eyes, 23 years old, 5'11"
  167.     if(add_person(My_Database,"Johnny","Brown","Blue",23,5,11))
  168.         return(-1); // error
  169. //  My_Database->debug_person(My_Database->people_list[0]);
  170.     (void)add_person(My_Database,"Sara","Blonde","Brown",41,5,3);
  171. //  My_Database->debug_person(My_Database->people_list[1]);
  172.     int i;
  173.     for(i = 0; i < My_Database->used; i++){
  174.         My_Database->debug_person(My_Database->people_list[i]);
  175.         printf("\n");
  176.     }
  177.     printf("\n");
  178.     My_Database->debug_all(My_Database);
  179.     printf("\n");
  180.    
  181.     uint8_t tmp;
  182.     printf("Query: Johnny\nFound?\n%s\n",((tmp=My_Database->query_person(My_Database,"Johnny")) == ((uint8_t)(-1)))?"No.":"Yes.");
  183.    
  184.     // Deallocation routine
  185.    
  186.     deallocate_data_header(My_Database);
  187.    
  188.     printf("\nPost deallocation:\n\n");
  189.     printf("Pointer for database:\t%p\n",My_Database);
  190.     My_Database->debug_all(My_Database);
  191.    
  192.     return(0); // success
  193. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement