#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2003
    Posts
    16
    Rep Power
    0

    Unhappy Passing pointers between functions


    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");

  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2002
    Posts
    272
    Rep Power
    23
    In initialise you are doing the following.

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

    car_hash_table is a local variable that will be obliterated by the call to fprintf following the call to initialise in main. You need to malloc/calloc the hash table.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2003
    Posts
    16
    Rep Power
    0
    Many thanks for your help! It's all working as intended now.

    Paul

IMN logo majestic logo threadwatch logo seochat tools logo