Thread: Dynamic Memory Allocation (malloc vs calloc)

  1. #1
    Registered User
    Join Date
    Jun 2010
    Posts
    36

    Dynamic Memory Allocation (malloc vs calloc)

    I am getting an error message saying that player is not initialize but I am trying to initialize it in my code on the line I am getting the error on. Ultimately I read in a file with a few players and the lottery numbers they selected. Then the user enters the winning numbers to see who has a match. I'm sure I can get that part once I get past this first hump.

    A sample input file is attached.

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    
    FILE* fin;
    FILE* fout;
    int i;
    
    struct players
    {
        char* last[19];
        char* first[19];
        int nums_played[6];
    };
    
    int main (void)
    {
        char filename[1024];
    
        int winners[6];
        int i, j;
        int ticketsbought = 0;
    //    struct players* player;
        
        //Ask user for the name of the file to read from
        printf("Please enter the name of the file with the ticket data \n");
    
        //Read in the file to read from
        scanf("%s", filename);
        
        //Open file for reading
        fin = fopen(filename, "r");
        
        //The first line will contain a single integer n, the total number of 
        //tickets bought. Now we will read in that first line
        fscanf(fin, "%d ", &ticketsbought); 
        
        //Dynamically allocate memory for the number of players in the input file
        for (i = 0; i < ticketsbought; i++)
        {
            struct players* player[i] = calloc(ticketsbought, sizeof(int));
        }
        
        //The first line will contain the last name of the ticket buyer, followed by 
        //a space, followed by the first name of the ticket buyer
        for (i = 0; i < ticketsbought; i++)
        {
            fscanf(fin, "%s ", &player[i]->last);
            printf("%s", player[i]->last);
            fscanf(fin, "%s ", &player[i]->first);
            printf("%s", player[i]->first);
            
            for (j = 1; j <= 6; j++)
            {  fscanf(fin, "%d ", &player[i]->nums_played[j]);
            printf("%d", player[i]->nums_played[j]);
            }   
        }
        
        //Ask the user for the winning combination of numbers
        printf("Please enter the winning lottery numbers:\n");
        scanf("%d %d %d %d %d %d", &winners[0], &winners[1], &winners[2], &winners[3], &winners[4], &winners[5]);
       
       //For debugging purposes only 
        for (i = 0; i < 6; i++)
        {
            printf("%d ", winners[i]);
        }
    
        //Close the input file
        fclose(fin);
         
        system("PAUSE");
        return 0;   
    }

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Do NOT use scanf to read strings.
    And now to the problem. You're declaring a LOCAL array player inside your for loop whose size you initialize to i. Unless you have C99, this won't work.
    You need to consider some things here. You want to dynamically create n players. So you allocate n of them and put a pointer to point to the first one. Then you can access them via the index operator.
    Note that the index operator dereferences, so using -> here is wrong!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    Jun 2010
    Posts
    36
    so how do you suggest i fix it?

  4. #4
    Registered User Char*Pntr's Avatar
    Join Date
    Sep 2007
    Location
    Lathrop, CA
    Posts
    198

    Smile

    Code:
    //Dynamically allocate memory for the number of players in the input file
        for (i = 0; i < ticketsbought; i++)
        {
            struct players* player[i] = calloc(ticketsbought, sizeof(int));
        }

    Hi, I'm lost and confused too... I don't understand why you're allocating memory for
    the size of an int... it seems that you should be allocating enough memory for
    the size of the object defined above in your players structure.

    As pointed out, you need to create n objects, and I don't see that will happen with
    the sizeof(int). Once your objects are created, create a pointer and intialize it to
    point to the first player.

    Do the simple stuff first. Swap out your scanf's on strings.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    If it isn't obvious, then let's go down another path.
    Explain to me why you thought it was a good idea to use a loop and a local pointer to allocate your memory?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Jun 2010
    Posts
    36
    I have since made some changes...this is what my code looks like now.

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    
    #define NUMBERS_PLAYED 6
    
    FILE* fin;
    FILE* fout;
    int i;
    
    struct players
    {
        char* last[19];
        char* first[19];
        int nums_played[6];
    };
    
    enum MATCHED
    {
        THREE = 10,
        FOUR = 1000,
        FIVE = 10000,
        SIX = 1000000    
    };
    
    int main (void)
    {
        char filename[1024];
        int winners[6];
        int i, j;
        int k;
        int* ptr;
        int ticketsbought = 0;
        
        //Ask user for the name of the file to read from
        printf("Please enter the name of the file with the ticket data. \n");
    
        //Read in the file to read from
        scanf("%s", filename);
        
        //Open file for reading
        fin = fopen(filename, "r");
        
        if(fin == NULL)
        {
            printf("Unable to open the file %s\n", filename);
            system("PAUSE");
            return 0;   
        }
        else
            printf("File opened successfully!\n\n");
        
        //The first line will contain a single integer n, the total number of 
        //tickets bought. Now we will read in that first line
        fscanf(fin, "%d ", &ticketsbought); 
       
        struct players player[ticketsbought];
       
        //Dynamically allocate memory for the number of players in the input file
        ptr = (int*)calloc(ticketsbought, sizeof(int));
        
        //The first line will contain the last name of the ticket buyer, followed by 
        //a space, followed by the first name of the ticket buyer
        for (i = 0; i < ticketsbought; i++)
        {
            fscanf(fin, "%s ", &player[i].last);
    //        printf("%s ", player[i].last);
            fscanf(fin, "%s ", &player[i].first);
    //        printf("%s \n", player[i].first);
            
            for (j = 1; j <= NUMBERS_PLAYED; j++)
            {  fscanf(fin, "%d ", &player[i].nums_played[j]);
    //        printf("%d ", player[i].nums_played[j]);
            }           
    //        printf("\n");
        }
        
        //Ask the user for the winning combination of numbers
        printf("Please enter the winning lottery numbers:\n");
        scanf("%d %d %d %d %d %d", &winners[0], &winners[1], &winners[2], &winners[3], &winners[4], &winners[5]);
       
       //For debugging purposes only 
        for (i = 0; i < NUMBERS_PLAYED; i++)
        {
            printf("%d ", winners[i]);
        }
        
        for (i = 0; i < j; i++)
        {
            for (j = 0; j < NUMBERS_PLAYED; j++)
            {
                for (k = 0; k < NUMBERS_PLAYED; k++)
                {
                    if (player[i].nums_played[j] == winners[k])
                    {
    //                    count++;
                    }
                }
            }
        } 
    
        //Close the input file
        fclose(fin);
         
        system("PAUSE");
        return 0;   
    }
    I feel like the nested FOR loops in particular are probably not the best method to do what I need it to do so if someone could give me some suggestions I would appreciate it. Also, I created a pointer called ptr but I am not referencing because I don't know where to do it at. I just know how to declare it from reading the book.

  7. #7
    Registered User
    Join Date
    Jun 2010
    Posts
    36
    Also, I would like to know if I am setting up the enums correctly. I haven't gotten to the point where I would use them just yet.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    You need to set up something to remember each persons count of winning numbers, don't you?

    Maybe add a "count" member into the player's struct, then if the number matches a winning number, you increment *that* player's count.

    In pseudo code, if you want to check all the winning numbers, in a batch mode:
    Code:
    for each number selected
       for each player
          for each number in their number array
             check if it's a winning number
    If you want to check each number as it's selected, you'd eliminate the first (outermost) for loop.

    Looks right to me.
    Last edited by Adak; 09-01-2010 at 01:25 AM.

  9. #9
    Registered User Char*Pntr's Avatar
    Join Date
    Sep 2007
    Location
    Lathrop, CA
    Posts
    198
    Ok, I understand now that you're only allocating enough memory for number of players.

  10. #10
    Registered User
    Join Date
    Jun 2010
    Posts
    36
    I have made some changes. Thank you all for your feedback. Now why am I getting an error when trying to access this portion in my code?

    Code:
         fscanf(fin, "%s ", &player[i].last);
    This is my full code:
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    
    #define NUMBERS_PLAYED 6
    
    FILE* fin;
    FILE* fout;
    int i;
    
    struct players
    {
        char* last[19];
        char* first[19];
        int nums_played[6];
        int count;
    };
    
    enum MATCHED
    {
        THREE = 10,
        FOUR = 1000,
        FIVE = 10000,
        SIX = 1000000    
    };
    
    int main (void)
    {
        char filename[1024];
        int winners[6];
        int i, j;
        int k;
        int ticketsbought = 0;
        struct player* players;
        
        //Ask user for the name of the file to read from
        printf("Please enter the name of the file with the ticket data. \n");
    
        //Read in the file to read from
        scanf("%s", filename);
        
        //Open file for reading
        fin = fopen(filename, "r");
        
        if(fin == NULL)
        {
            printf("Unable to open the file %s\n", filename);
            system("PAUSE");
            return 0;   
        }
        else
            printf("File opened successfully!\n\n");
        
        //The first line will contain a single integer n, the total number of 
        //tickets bought (number of players). Now we will read in that first line
        fscanf(fin, "%d ", &ticketsbought); 
       
       
        //Dynamically allocate memory for the number of players in the input file
        players = malloc(ticketsbought * sizeof(struct players));
    
          
        //The first line will contain the last name of the ticket buyer, followed by 
        //a space, followed by the first name of the ticket buyer
        for (i = 0; i < ticketsbought; i++)
        {
            fscanf(fin, "%s ", player[i].last);
            fscanf(fin, "%s ", &player[i].first);
            
            for (j = 1; j <= NUMBERS_PLAYED; j++)
            {  fscanf(fin, "%d ", &player[i].nums_played[j]);
            }           
        }
        
        //Ask the user for the winning combination of numbers
        printf("Please enter the winning lottery numbers:\n");
        scanf("%d %d %d %d %d %d", &winners[0], &winners[1], &winners[2], &winners[3], &winners[4], &winners[5]);
       
       //For debugging purposes only 
        for (i = 0; i < NUMBERS_PLAYED; i++)
        {
            printf("%d ", winners[i]);
        }
        
        //For each number selected
        for (i = 0; i < NUMBERS_PLAYED; i++)
        {
            //For each player
            for (j = 0; j < ticketsbought; j++)
            {
                //For each number in their array
                for (k = 0; k < NUMBERS_PLAYED; k++)
                {
                    //Check to see if it's a winning number
                    if (player[i].nums_played[j] == winners[k])
                    {
                        //Increment the counter for the particular player if a number
                        //that they played is a match against the winning numbers
                        player[i].count++;                    
                    }
                }
            }
        }
        
        //Final Output
        for (i = 0; i < ticketsbought; i++)
        {
            if (player[i].count >= 3)
                printf("%s %s matched %d numbers and won $%d.\n", player[i].first, player[i].last, player[i].count);   
        }
    
        //Close the input file
        fclose(fin);
        free(players);
         
        system("PAUSE");
        return 0;   
    }
    It is telling me that 'player' is undeclared . Am I saving it to the wrong location? I didn't think I had to separately declare an array of struct players* player 's. Let me know if I'm wrong. Thanks!!
    Last edited by lostandconfused; 09-01-2010 at 03:22 PM. Reason: Forgot to add full code

  11. #11
    Registered User
    Join Date
    Jun 2010
    Posts
    36
    Yes, char* pntr. That is correct.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Bug in Best-Fit Memory Allocation program (Simulation)
    By RommelTJ in forum C Programming
    Replies: 6
    Last Post: 12-13-2009, 04:43 PM
  2. Dynamic Memory Allocation (Seg. Fault)
    By dr_jaymahdi in forum C++ Programming
    Replies: 10
    Last Post: 09-30-2007, 02:02 PM
  3. dynamic memory allocation problem
    By firyace in forum C Programming
    Replies: 4
    Last Post: 05-23-2007, 09:57 PM
  4. Dynamic Memory Allocation Question
    By Piknosh in forum C++ Programming
    Replies: 1
    Last Post: 04-14-2004, 01:55 PM
  5. Manipulating the Windows Clipboard
    By Johno in forum Windows Programming
    Replies: 2
    Last Post: 10-01-2002, 09:37 AM

Tags for this Thread