Hi,

I have been having a big problem passing pointers between functions and really need some help!

My program consists of a main function which calls other functions I've defined in a header file.

When the program runs, main calls a function to set up an array of struct pointers. Each element in the array is assigned a particular struct (hash table). If there is a collision (more than one struct is assigned to a particular element of the array), a linked list is constructed, where the first struct points to the next in the list, and so on. When the array is finished, it looks something like this (cut down example):


ARRAY

0 ----> struct ----> struct

1 ----> struct

2 ----> struct ----> struct ----> struct

3 ----> struct ----> struct

4 ----> struct ----> struct ----> struct


In main, I have initialised a structure (p_car_data) which contains a pointer of type struct pointer (i.e. it's a pointer to a pointer of type struct), called mp_car_table.

Main passes this structure to the first function, and when the array is complete, as above, it makes the pointer point at the array:

PHP Code:
p_car_data->mp_car_table car_hash_table
when the function exits, main is able to access the elements in the array, any any structs pointed to in linked lists as shown above.

PHP Code:
p_car_data->mp_car_table[3]->member 
The problem I am having occurs when main passes this structure to other functions, hoping to access the array - all the struct pointers are lost!

I'm not sure why it's doing this, maybe I've made some mistake with pointers...

Can anyone help?

Thanks in advance

Paul

P.S. I have to stick with this structure (passing a structure containing the array pointer to the function, etc), as this is one part of a much larger program, and it's too late to turn back and change things...


Below (and also attached) is a small program which simulates the problem (the real program is too big to post here):
The example uses structs which represent cars, with make, model and value as the members.

PHP Code:

/*
// Main - calls the functions in doHash.h
//
// Passes a pointer to a struct to functions (p_car_data) 
// p_car_data contains a pointer to the array created in initialise
// The array can be accessed in main (after initialise finishes), 
// but not when passed from main to subsequent functions (print_cars)
//
*/

#include "stdafx.h"
#include "string.h"
#include "stdlib.h"
#include "doHash.h"

int main(void) {

   
/* Initialise the struct containing the array pointer */
   
data_return_t *p_car_data;

   
p_car_data = (data_return_t *)calloc(1sizeof(data_return_t));

   if (!
p_car_data) {
      
fprintf(stderr"Memory allocation error!\n");
      exit(
0);
   }

   
/* Set up the array, pass the struct pointer to initialise function */
   
initialise(p_car_data);

   
/* Array pointer in struct working fine here */
   
fprintf(stderr"\n\nFirst car: %s"p_car_data->mp_car_table[0]->mp_make);

   
/* Pass the same struct pointer to another function - all pointers to structs in p_car_data->mp_car_table (array) are lost! */
   
print_cars(p_car_data);

   return 
0;
}



/*
// Header file containing functions - doHash.h
//
*/

typedef struct car {

   
unsigned int value;
   
char *mp_make;
   
char *mp_model;
   
struct car *mp_next;

car_t;

typedef struct data_tables {

   
struct car **mp_car_table;
   
int total_value;

data_return_t;


void add_new_car(car_t **car_hash_tablechar *s_makechar *s_modelunsigned int valueunsigned int element);

void print_cars(data_return_t *car_data);

int initialise(data_return_t *p_car_data) {

   
unsigned int element;
   
int i;
   
int a;
   
int value;
   
int total_value 0;
   
char s_make[10];
   
char s_model[10];

   
car_t *car_hash_table[10] = {NULL};

   
/* Get the car make and model */
   
for (0100i++) {

      
5;

      if (
== 0) {
         
strncpy(s_make"Ford"4);
         
s_make[4] = '\0';
         
strncpy(s_model"Escort"6);
         
s_model[6] = '\0';
         
value 3000;
      }

      if (
== 1) {
         
strncpy(s_make"Vauxhall"8);
         
s_make[8] = '\0';
         
strncpy(s_model"Astra"5);
         
s_model[5] = '\0';
         
value 4500;
      }

      if (
== 2) {
         
strncpy(s_make"VW"2);
         
s_make[2] = '\0';
         
strncpy(s_model"Beetle"6);
         
s_model[6] = '\0';
         
value 3000;
      }

      if (
== 3) {
         
strncpy(s_make"Jaguar"6);
         
s_make[6] = '\0';
         
strncpy(s_model"XK8"3);
         
s_model[3] = '\0';
         
value 30000;
      }

      if (
== 4) {
         
strncpy(s_make"Lotus"5);
         
s_make[5] = '\0';
         
strncpy(s_model"Esprit"6);
         
s_model[6] = '\0';
         
value 25000;
      }

      
/* Calculate element in array to use - arbitrary value between 0 and 9 */
      
element rand() % 10;

      
/* Add car to array */
      
add_new_car(car_hash_tables_makes_modelvalueelement);
      
total_value total_value value;
   }

   
/* Set pointer to cars array in the data struct */
   
p_car_data->mp_car_table car_hash_table;
   
p_car_data->total_value total_value;

   
/* Print out listing of all cars */
   
print_cars(p_car_data);
   return 
0;
}

void add_new_car(car_t **car_hash_tablechar *s_makechar *s_modelunsigned int valueunsigned int element) {

   
/* Add a new car (struct) to the hash table */
   
car_t *p_tmp_car;
   
car_t *p_new_car;

   
p_new_car = (car_t *)calloc(1sizeof(car_t));
   if (!
p_new_car) {
      
/* CRITICAL ERROR: calloc failed */
      
exit(0);
   }

   
p_new_car->mp_make = (char *)calloc(10sizeof(char));
   if (!
p_new_car->mp_make) {
      
/* CRITICAL ERROR: calloc failed */
      
exit(0);
   }
   
strncpy(p_new_car->mp_makes_make10);

   
p_new_car->mp_model = (char *)calloc(10sizeof(char));
   if (!
p_new_car->mp_model) {
      
/* CRITICAL ERROR: calloc failed */
      
exit(0);
   }
   
strncpy(p_new_car->mp_models_model10);

   
p_new_car->value value;

   
/* Add new car to array */
   /* If collision, make last struct in list from that element point to new struct */
   
if (car_hash_table[element] == NULL) {
      
car_hash_table[element] = p_new_car;
   }
   else {
      
p_tmp_car car_hash_table[element];

      while(
p_tmp_car->mp_next != NULL) {
         
p_tmp_car p_tmp_car->mp_next;
      }

      
p_tmp_car->mp_next p_new_car;
   }
}

void print_cars(data_return_t *car_data) {

   
/* Print all structs linking to the hash table */
   
unsigned int i;
   
car_t *p_tmp_car;

   
fprintf(stderr"\nTotal value of cars is: %d "car_data->total_value);

   for(
010i++) {
      
p_tmp_car car_data->mp_car_table[i];
      if (
p_tmp_car) {
         while(
1) {
            
fprintf(stderr"\nElement: %d Make: %s, Model: %s"ip_tmp_car->mp_makep_tmp_car->mp_model);
            
/* If there is another car in the list, print it */
            
if (p_tmp_car->mp_next) {
               
p_tmp_car p_tmp_car->mp_next;
            }
            else {
               break;
            }
         }
      }
   }

   
fprintf(stderr"\n\n");