Array of pointers

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • fauxanadu
    New Member
    • Mar 2007
    • 60

    Array of pointers

    Hello:

    I've been working on an assignment and I have hit a stumbling block pertaining to an array of pointers.

    If I am correct in my assumptions, the array

    Code:
    struct animal* zoo[4]
    should have its address passed to a function when calling it like this:

    Code:
    somefunc(zoo);
    Once I am in somefunc, if I call the line of code:

    Code:
    free(zoo[0]);
    zoo[0] = 0;
    causes the program to crash. Specifically the error is commented out on line 261 of hw2************ ***Driver.c below. Thank you to anyone who can enlighten me on why this seemingly innoculous line is causing the program to crash.

    -fauxanadu

    hw2************ ***Constants.c
    [CODE=c]
    /*************** *************** *************** *************** *************** ***
    * PROGRAMMER : *************** *
    * LANGUAGE : C *
    * CLASS : CSE 1320-002, Fall 2007 *
    * COMPILER : gcc *
    * OPERATING SYSTEM : Unix *
    * PLATFORM : omega *
    * COURSE : Intermmediate Programming *
    * ASSIGNMENT : Homework 1 *
    * ASSIGNED : 27 September 2007 *
    * DUE : 16 October 2007 *
    * FILED AS : hw2************ ***Constants.c *
    * FILES USED : hw2************ ***Constants.c *
    * : hw2************ ***Driver.c *
    * CONCEPTS : Structures, dynamic memory (de)allocation, file I/O *
    * : Command Line Arguments *
    * WEIGHT : 10% of Final Grade *
    * PURPOSE : Include required system files *
    * Define global constants *
    * Prototype Functions *
    *************** *************** *************** *************** *************** **/
    // System Files
    #include <stdlib.h>
    #include <stdio.h>

    // Constants
    #define CMD_ARGS 2
    #define CMD_CHAR '*'
    #define CMD_INDEX 0
    #define CTRL_INDEX 1
    #define CTRL_END 'E'
    #define CTRL_FEED 'f'
    #define CTRL_PRCH 'p'
    #define CTRL_TRAN 't'
    #define DISP_FLOAT 4
    #define DISP_INT 4
    #define DISP_NAME 11
    #define DISP_PREC 1
    #define DISP_STRING 7
    #define ERR_NONE 0
    #define ERR_BAD_ARGS 1
    #define ERR_MISSING_FIL E 2
    #define ERR_MALFORMED 3
    #define FALSE 0
    #define FILE_INDEX 1
    #define LINE_SIZE 51
    #define LOW_INDEX 0
    #define NULLS '\0'
    #define NULLP 0
    #define STRING_LARGE 20
    #define STRING_SMALL 10
    #define STARTI 0
    #define STARTT 0
    #define TRUE 1
    #define ZEROF 0.0
    #define ZEROI 0
    #define ZOO_SIZE 4

    // Objects
    struct Animal
    {
    char color[STRING_LARGE];
    char name[STRING_LARGE];
    char species[STRING_LARGE];
    double food;
    double water;
    int age;
    int id;
    int weight;
    };

    // Function Prototypes
    void purchase(FILE** , struct Animal*[], char[]);
    void maintain(FILE** , struct Animal*[], char[]);
    void report(struct Animal*[]);
    void transfer(FILE** , struct Animal*[], char[]);
    [/CODE]

    hw2************ ***Driver.c
    [CODE=c]/*************** *************** *************** *************** *************** **
    * PROGRAMMER : *************** * *
    * LANGUAGE : C *
    * CLASS : CSE 1320-002, Fall 2007 *
    * COMPILER : gcc *
    * OPERATING SYSTEM : Unix *
    * PLATFORM : omega *
    * COURSE : Intermmediate Programming *
    * ASSIGNMENT : Homework 1 *
    * ASSIGNED : 27 September 2007 *
    * DUE : 16 October 2007 *
    * FILED AS : hw2************ ***Driver.c *
    * FILES USED : hw2************ ***Constants.c *
    * : hw2************ ***Driver.c *
    * CONCEPTS : Structures, dynamic memory (de)allocation, file I/O *
    * : Command Line Arguments *
    * WEIGHT : 10% of Final Grade *
    * PURPOSE : Define Functions *
    *************** *************** *************** *************** *************** **/

    #include "hw2*********** *****Constants. c"

    int main(int argc, char* argv[])
    {
    //Variable Declaration
    char lineIn[LINE_SIZE] = {NULLS};
    FILE* input = {ZEROI};
    struct Animal* zoo[ZOO_SIZE] = {NULLP};

    // Checks that there were 2 arguments passed at the command line
    if(argc != CMD_ARGS)
    {
    printf("\nError %d", ERR_BAD_ARGS);
    printf("\nThe proper syntax is:");
    printf("\n>exec utable.exe file.dat\n");
    exit(ERR_BAD_AR GS);
    }

    // Opens the file and checks for success
    input = fopen(argv[FILE_INDEX], "r");
    if (!input)
    {
    printf("\nError %d", ERR_MISSING_FIL E);
    printf("\nThe file %s could not be opened. \n", argv[FILE_INDEX]);
    exit(ERR_MISSIN G_FILE);
    }

    // Gets a line of input and determines which function to call
    fgets(lineIn, LINE_SIZE - 1, input);
    while(!(lineIn[CMD_INDEX] == CMD_CHAR & lineIn[CTRL_INDEX] == CTRL_END))
    {
    printf("\n");
    if(lineIn[CMD_INDEX] == CMD_CHAR)
    {
    switch(lineIn[CTRL_INDEX])
    {
    case CTRL_FEED:
    maintain(&input , zoo, lineIn);
    break;
    case CTRL_PRCH:
    purchase(&input , zoo, lineIn);
    break;
    case CTRL_TRAN:
    transfer(&input , zoo, lineIn);
    break;
    default:
    printf("\nError %d", ERR_MALFORMED);
    printf("\nThe input file is malformed.");
    printf("\nPleas e consult the documentation\n ");
    exit(ERR_MALFOR MED);
    }
    }
    report(zoo);
    }

    return ERR_NONE;
    }

    void purchase(FILE** input, struct Animal* zoo[], char lineIn[])
    {
    //Variable Declaration
    int i = ZEROI;
    char a[STRING_SMALL], b[STRING_SMALL], c[STRING_SMALL],
    d[STRING_SMALL], e[STRING_SMALL], f[STRING_SMALL],
    g[STRING_SMALL];

    //Gets line of input
    fgets(lineIn, LINE_SIZE - 1, *input);

    //Exit Condition
    if(lineIn[CMD_INDEX] == CMD_CHAR)
    {
    return;
    }

    for(i = STARTI; i < ZOO_SIZE; i++)
    {
    if (zoo[i] == NULLP)
    {
    zoo[i] = (struct Animal*)malloc( 1 * sizeof(struct Animal));
    sscanf(lineIn, "%s%s%s%s%s%s%s ", a, b, c, d, e, f, g);
    strcpy(zoo[i]->species, a);
    strcpy(zoo[i]->name, b);
    if(!(isdigit(c[LOW_INDEX])))
    {
    strcat(zoo[i]->name, " ");
    strcat(zoo[i]->name, c);
    zoo[i]->age = atoi(d);
    zoo[i]->weight = atoi(e);
    zoo[i]->id = atoi(f);
    strcpy(zoo[i]->color, g);
    }
    else
    {
    zoo[i]->age = atoi(c);
    zoo[i]->weight = atoi(d);
    zoo[i]->id = atoi(e);
    strcpy(zoo[i]->color, f);
    }
    zoo[i]->food = ZEROF;
    zoo[i]->water = ZEROF;
    printf("Purchas ing: %s\n", zoo[i]->name);
    break;
    }
    }

    //Makes sure the for loop exited early, if not, inform user
    if(i >= ZOO_SIZE)
    {
    sscanf(lineIn, "%s%s%s%s%s%s%s ", a, b, c, d, e, f, g);
    printf("Purchas e failed: %s ", b);
    if(!(isdigit(c[LOW_INDEX])))
    {
    printf("%s ", c);
    }
    printf("\n");
    }

    //Recurses and then returns
    purchase(input, zoo, lineIn);
    return;
    }

    void maintain(FILE** input, struct Animal* zoo[], char lineIn[])
    {
    //Variable Declaration
    int i = ZEROI;
    char a[STRING_LARGE], b[STRING_SMALL], c[STRING_SMALL], d[STRING_SMALL];

    //Gets line of input
    fgets(lineIn, LINE_SIZE - 1, *input);

    //Exit Condition
    if(lineIn[CMD_INDEX] == CMD_CHAR)
    {
    return;
    }

    //Separates out the desired data
    sscanf(lineIn, "%s%s%s%s", a, b, c, d);
    if(!(isdigit(b[LOW_INDEX])))
    {
    strcat(a, " ");
    strcat(a, b);
    }

    for(i = STARTI; i < ZOO_SIZE; i++)
    {
    if(!(strcmp(zoo[i]->name, a)))
    {
    printf("Maintai ning: %s\n", zoo[i]->name);
    if(isdigit(b[LOW_INDEX]))
    {
    zoo[i]->food = atof(b);
    zoo[i]->water = atof(c);
    }
    else
    {
    zoo[i]->food = atof(c);
    zoo[i]->water = atof(d);
    }
    }
    }

    //Recurses and then returns
    maintain(input, zoo, lineIn);
    return;
    }

    void report(struct Animal* zoo[])
    {
    //Variable Declaration
    static int headerPrinted = FALSE;
    static int i = ZEROI;

    //Exit condition
    if(i >= ZOO_SIZE)
    {
    return;
    }

    //If the header has not been printed, prints it
    if(headerPrinte d == FALSE)
    {
    printf("----+------------+--------+-----+-------+--------+------+------\n");
    printf("ID |Name |Species |Age |Weight |Color |Food |Water \n");
    printf("----+------------+--------+-----+-------+--------+------+------\n");
    headerPrinted = TRUE;
    }
    if(zoo[i])
    { //Prints out the current animals information
    printf("%-*d|%-*s |%-*s |%*d | %*d |%-*s | %*.*f | %*.*f \n",
    DISP_INT, zoo[i]->id,
    DISP_NAME, zoo[i]->name,
    DISP_STRING, zoo[i]->species,
    DISP_INT, zoo[i]->age,
    DISP_INT, zoo[i]->weight,
    DISP_STRING, zoo[i]->color,
    DISP_FLOAT, DISP_PREC, zoo[i]->food,
    DISP_FLOAT, DISP_PREC, zoo[i]->water);
    }

    //Recurses and resets variables for next print
    i++;
    report(zoo);
    headerPrinted = FALSE;
    i = ZEROI;
    return;
    }






    void transfer(FILE** input, struct Animal* zoo[], char lineIn[])
    {
    //Variable Declaration
    int i = ZEROI;
    char a[STRING_SMALL];

    //Gets line of input
    fgets(lineIn, LINE_SIZE - 1, *input);

    //Exit Condition
    if(lineIn[CMD_INDEX] == CMD_CHAR)
    {
    return;
    }

    //Separates out the desired information
    sscanf(lineIn, "%s%s%s%s%s%s%s ", a);

    //Checks each element of the zoo to see if it matches
    for(i = ZEROI; i < ZOO_SIZE; i++)
    {
    if(!(strcmp(zoo[i]->name, a)))
    {
    printf("Transfe ring: %s\n", zoo[i]->name);
    free((struct Animal*)zoo[i]);
    //zoo[i] = (struct Animal*)NULLP;
    break;
    }
    }

    if(i >= ZOO_SIZE)
    {
    printf("Transfe r Failed: %s", lineIn);
    }

    //Recurses and then returns
    transfer(input, zoo, lineIn);
    return;
    }[/CODE]
  • mattmao
    New Member
    • Aug 2007
    • 121

    #2
    Hi.

    I've no time so I skip your assignment requirements:(

    But you can see my sample code for the array of structs:

    Code:
      #include <stdio.h>
    
    struct rectangle
    {
       int width, height;
    };
    
    int main()
    {
       struct rectangle recArray[10];
       int i;
    
       for(i=0; i<10; i++)
          recArray[i].width = i;
       
       for(i=0; i<10; i++)
          printf("%d ", recArray[i].width);
    
       return;
      
    }
    And the result:
    Code:
    charlie$ gcc structarray.c
    charlie$ ./a.out          
    0 1 2 3 4 5 6 7 8 9 charlie$
    I think this would help you to access the "properties " inside each of the struct "elements". ..

    Comment

    • fauxanadu
      New Member
      • Mar 2007
      • 60

      #3
      I have to use an array of dynamically allocated pointers. I can't figure out why:
      zoo[0] = 0;

      is causing the program to crash. zoo is defined as
      struct animal* zoo[4];

      and is sent to a function via
      somefunc(zoo);

      Once in somefunc, the assignment mentioned at the top of this post causes the program to crash.

      Comment

      • mattmao
        New Member
        • Aug 2007
        • 121

        #4
        Hi

        zoo[0] is the "address to first struct element", you cannot assign an int to that address...

        I would suggest you take more time reading the lecture notes for better understanding about this god damned issue...

        I am doing my assignment2, which requires a linked list of linked lists...

        Comment

        • fauxanadu
          New Member
          • Mar 2007
          • 60

          #5
          I have read the lecture notes quite throughly and this part of the program is actually a direct copy of what the professor has in his notes. I cannot figure out why it will not work in this context.

          Comment

          • mattmao
            New Member
            • Aug 2007
            • 121

            #6
            Well, as for me I would use this:

            struct rectangle recArray[10];

            It means an array of struct elements, each of which could be accessed by using recArray[i].

            I don't know why your pro would use struct somecClass *array[10];

            I don't know how to do this job in thay way:(

            Comment

            • RRick
              Recognized Expert Contributor
              • Feb 2007
              • 463

              #7
              Your problem is a one of initialization. You are trying to free something that is pointed to by an uninitialized pointer.

              [code=c]struct animal * zoo[4];[/code]
              This code will create an array of 4 pointers to a struct animal. This does not set any of the pointer values in zoo, so using zoo[0] will access something with a bad pointer.

              Later on you try to free zoo[0] and this is probably what is causing your program to blow up. If you want to free something, the pointer has to be either NULL or a valid pointer value (i.e, created by malloc,etc.).


              One solution is to initialize zoo when you declare it.
              [code=c]struct animal * zoo[4] = { NULL, NULL, NULL, NULL};[/code] should fix the problem.

              Comment

              • fauxanadu
                New Member
                • Mar 2007
                • 60

                #8
                It is actually initialized to null. (on line 28.):
                28. struct Animal* zoo[ZOO_SIZE] = {NULLP};

                With NULLP being equal to 0.

                In the main function I can set zoo[0] = 0; just fine and it works. Once I pass the address of zoo to a function, inside that function the exact same assignment stops working. That is the problem. I need to know why as I cannot figure it out. I've been working on this problem for three nights intermittantly and it just won't work no matter what I do.

                Comment

                • RRick
                  Recognized Expert Contributor
                  • Feb 2007
                  • 463

                  #9
                  There are over 300 lines of code, an unknown data file, and even recursive calls. This can get complicated, very quickly.

                  You need to narrow down the scope of the problem and figure out the location where the problem occurs. What is needed to reproduce this problem? We also need values for zoo before and after the problem area is called.

                  Comment

                  Working...