Thread: Array of structs: function passing

  1. #1
    Registered User
    Join Date
    Sep 2010
    Posts
    10

    Array of structs: function passing

    I have an array of structs created with an initial size and filled with the members of the struct tag. as such

    Code:
    struct employee{
    	
    	char fullname[30];
    	float salary;
    	char fulldate[40];
    };
    
    struct employee my_employee[MAXSIZE]= {
    
        {"Johnson, larry", 233333.3, "December, 4th 1999\n"},
    	 {"Kobe, Bryant", 90999.23, "September, 3rd, 1922\n"},
    	 {"Lebron, James", 43334.43, "January, 5th 1932"},
    	 {"Jermaine, O'neal", 5556677.4, "January, 5th 1932"},
    	 {"Dwayne, Wade", 55556.4, "January, 7th 1932"}
    	 
     }; 
    
    Then i want to use that array (my_employee in a function) that will add another struct and print all the details in the struct.
    HERE IS MY CODE // WHY WONT THIS WORK
    
    void add_employee(struct employee  my_employee[]){
    	int i;
    	my_employee = malloc(200);
    	struct employee *tempRecs;
    	tempRecs = (struct employee *)malloc((size+1)*sizeof(struct employee));
    	memcpy(tempRecs, my_employee, size*sizeof(struct employee));	
    	for(i = 0; i < size; i++) {
    		tempRecs[i] = (my_employee)[i];
    
    			}
    	
    	
    	printf("Please Enter Employee Full name:\n");
    	scanf("%s", tempRecs->fullname);
    	printf("Please Enter Employee salary");
    	scanf("%f", &tempRecs->salary);
    	printf("Please Enter Current Date (Month, DayYear)");
    	scanf("%s", tempRecs[size].fulldate);
    	size++;
    	free( my_employee);
        my_employee = tempRecs;
    
    }

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    It's about scoping and where variables are valid and not... Think about passing a pointer to an employee struct instead of the struct itself...

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by warsame
    Then i want to use that array (my_employee in a function) that will add another struct and print all the details in the struct.
    HERE IS MY CODE // WHY WONT THIS WORK
    I think that you are over-complicating the code. You do not need to use malloc and free here. Rather, keep track of the number of elements of the struct employee array that are in use. Pass that number (or a pointer to the variable) as an argument to add_employee, which can then simply copy over the values for the next struct employee object.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Sep 2010
    Location
    Halesowen, England
    Posts
    30
    What is this line doing?
    Code:
    my_employee = malloc(200);
    As far as I can see, it would cause you to lose the contents of my_employee every time add_employee is called.

  5. #5
    Registered User
    Join Date
    Sep 2010
    Posts
    10
    i am using malloc because i want to only create enough space for just
    one struct everytime add_employee is called. as far as using a struct employee
    pointer to point to my array of structs the following code gives me an
    error:
    [code]

    struct employee *mainDatabase;
    mainDatabase = &myEmployee[0]; // i want to start at the first struct in
    array of structs and if increase mainDatabse++ that hopefully will give me
    the next struct in my array of structs??

    how do i use a pointer in my add_employee fucntion to create 4 bytes of pointer space when it is used??

    add_employee(struct employee *my_employee) // is this correct?

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    You can't have your cake and eat it too.

    malloc() and free() do not provide a means to magically resize an array that was declared and defined at compile time.

    The basic rule is that free(ptr) is invalid unless ptr is a value returned by malloc() [or a related function].

    Your code - indirectly - passes a pointer to free() that was not returned by malloc(). Hence it is invalid.

    Either provide MAXSIZE with a value that is larger than your code will ever need (which is essentially what laserlight described) or ensure your array is malloc()'ed BEFORE you ever attempt to free() it.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Registered User
    Join Date
    Dec 2008
    Posts
    15
    I'm not sure if I'm really helping but this is how I would solve it. I tried to simplify it.

    Code:
    #include <stdio.h>
    #include <string.h>
    
    struct employee{
        char fullname[30];
        float salary;
        char fulldate[40];
    };
    
    int main (void){
      int i;
      struct employee *my_employee[MAXSIZE]; 
    
      struct employee add_employee(char *name, float salary, char *date ){
    	struct employee temp;
            strcpy(temp.fullname,name);
            temp.salary=salary;
            strcpy(temp.fulldate,date);
            return temp;
      };
    
    
      // add employee info
      for(i = 0; i < MAXSIZE; i++)
         
        my_employee[i]=(struct employee)malloc(sizeof(struct employee));
        
        // returns a struct
        //get arguments using scanf()
        my_employee[i]=add_employee(<pass arguments >);
    
        //print data
        //free memory 
    
        return 0;
    }

  8. #8
    Registered User
    Join Date
    Sep 2010
    Posts
    10
    so if i dont use a struct array but instead create something like this

    Code:
    struct employee my_employee = {
    
        "Johnson, larry", 233333.3, "December, 4th 1999	
    	 
     }; 
    struct employee *tempRecs;
    tempRecs = &my_employee; // this line gives me the error " conflicting types for 
    tempRecs"
    
    i now want to have one struct and keep adding to this struct by allocating space and copying over elements every time. is this possible?

  9. #9
    Registered User
    Join Date
    Dec 2008
    Posts
    15
    I'll try and help , but post the exact and complete code that you are using to get that particular error.

  10. #10
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    You either want to have a struct, or you want to have an array of structs.

    An array of X is something different from an X.

    If you want to have one struct that you "add to", you are expecting an X to act as if it is a (resizable) array of X. Or you want to be allowed to act as if it is.

    Such requirements are muddled and ambiguous. And one requirement when programming a computer is that you specify things unambiguously. A computer does not handle ambiguity well.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  11. #11
    Registered User
    Join Date
    Sep 2010
    Posts
    10
    ITS SEEMS I HAVE CONFUSED MYSELF,
    i have posted all of my code here. i simply want to have a pointer to a struct that
    will allocate space when called accordingly and a temporary struct pointer that will serve as
    my new struct which will copy all the values in the struct and the user added struct to then update my print struct function. HERE IS MY FULL CODE
    Code:
    #include <string.h>
    #define MAXSIZE 5
    int size =0;
    struct employee{
    	
    	char fullname[30];
    	float salary;
    	char fulldate[40];
    };
    struct employee *tempRecs;
    struct employee my_employee = {
    
        "Johnson, larry", 233333.3, "December, 4th 1999"
    
     }; 
    
    
    
    
    void print_records(){
    
    	struct employee *mainDatabase = &my_employee;
    
    	printf("\nFull Name: '%s'\n", mainDatabase->fullname);
    	printf("Salary: $%.2f\n" , mainDatabase->salary);
    	printf("Date Hired: %s\n", mainDatabase->fulldate);
    	mainDatabase++;
    }
    
    void add_employee(struct employee  **my_employee){
    	int i;
    	struct employee *tempRecs;
    	my_employee = (struct employee **)malloc((size + 1)*sizeof(struct employee *));
    
    	tempRecs = (struct employee *)malloc((size+1)*sizeof(struct employee));
    	memcpy(tempRecs, my_employee, size*sizeof(struct employee));	
    	for(i = 0; i < size; i++) {
    		tempRecs[i] = (*my_employee)[i];
    
    			}
    	
    	
    	printf("Please Enter Employee Full name:\n");
    	scanf("%s", tempRecs->fullname);
    	printf("Please Enter Employee salary");
    	scanf("%f", &tempRecs->salary);
    	printf("Please Enter Current Date (Month, DayYear)");
    	scanf("%s", tempRecs[size].fulldate);
    	size++;
    	free( *my_employee);
        *my_employee = tempRecs;
    
    }

  12. #12
    Registered User
    Join Date
    Dec 2008
    Posts
    15
    where is main()? And you should add

    Code:
     #include <stdlib.h>
    since you are using the malloc() function.

  13. #13
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    I liked your first idea - make MAXSIZE something BIG - maybe 200 or so, and use the static array idea, instead of malloc() and realloc(). Your program will keep track of how many records are active in your database, all the time. Add a record, the count goes up by one, delete a record, and you decrement the count by one, as well.

    When you delete a person, don't delete them - just zero out their name and/or ID number or both. (You have to watch it, there WILL be people with duplicate names).

    Now your display and add functions know that anyone with a zeroed out name and ID, will not be displayed for normal searches, and are available to put a new record, right into that space.

    Leave malloc() and realloc() out of it, until you have a bit more C under your belt. I hear you saying "but what am I going to do when I run out of space?".

    Simple, you read in another 200 names from the data file, and carry on, like before. No, it's not perfect, but you can NEVER hold all the records in a database, in main memory, unless it's rather tiny. Using malloc and realloc will help, but they usually only put off the inevitable - you have to be able to read your records, from a source other than main memory - sooner or later.

  14. #14
    Registered User
    Join Date
    Sep 2010
    Posts
    10
    Quote Originally Posted by Adak View Post
    I liked your first idea - make MAXSIZE something BIG - maybe 200 or so, and use the static array idea, instead of malloc() and realloc(). Your program will keep track of how many records are active in your database, all the time. Add a record, the count goes up by one, delete a record, and you decrement the count by one, as well.

    When you delete a person, don't delete them - just zero out their name and/or ID number or both. (You have to watch it, there WILL be people with duplicate names).

    Now your display and add functions know that anyone with a zeroed out name and ID, will not be displayed for normal searches, and are available to put a new record, right into that space.

    Leave malloc() and realloc() out of it, until you have a bit more C under your belt. I hear you saying "but what am I going to do when I run out of space?".

    Simple, you read in another 200 names from the data file, and carry on, like before. No, it's not perfect, but you can NEVER hold all the records in a database, in main memory, unless it's rather tiny. Using malloc and realloc will help, but they usually only put off the inevitable - you have to be able to read your records, from a source other than main memory - sooner or later.
    i have actually solved this problem without using malloc and reaalloc, i know want to use these two and ignore file system reading for the moment, i am trying to learn the machine architecture of the c language and need help to allocate memory for a pointer, copy all current records to that pointer using a loop and then set the pointer free().... and so on.

  15. #15
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    i am trying to learn the machine architecture of the c language and need help to allocate memory for a pointer, copy all current records to that pointer using a loop and then set the pointer free().... and so on.
    You can't "copy all current records to that pointer", because a pointer (any pointer), can only hold ONE address. You mean "copy all current records into a block of allocated memory the array points to".

    First thing, is you need to include stdlib.h if you want to use malloc(). Also, you should have stdio.h included, as well.

    Did you add in main() function, yet?

    Add that, and then report what your errors are.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 11
    Last Post: 12-30-2009, 04:04 PM
  2. function passing argument..array ?
    By jochen in forum C Programming
    Replies: 2
    Last Post: 09-30-2007, 11:53 AM
  3. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  4. passing array of structures to function
    By bvnorth in forum C Programming
    Replies: 3
    Last Post: 08-22-2003, 07:15 AM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM