Thread: poiner to structure problem

  1. #1
    Registered User bluetxxth's Avatar
    Join Date
    Feb 2010
    Location
    sweden
    Posts
    43

    poiner to structure problem

    Hi everybody!


    To make a long story short....

    say I have a structure

    Code:
    struct employee {
        int emp_index; //To assign a value to each employee for a later "pointing"
        char name[30];
        char address[100];
        int age;
        float salary;
    } emp_ptr[N];

    I fill an array with this structure. Assume that emp_num is fed by user input earlier

    Code:
    printf("Populating staff......... \n\n");
        for (d = 1; d <= emp_num; d++)
            emp_ptr[emp_num];

    say I declare a pointer like this

    Code:
        void *ptr = &emp_ptr[d]; // here ptr points at the address of the array of employees
        ptr = malloc(sizeof (struct employee) * d); // memory allocation for the previous line - is this right?
    If at a later stage in my code I want to recall a particular employee on the array....

    can I do it like this?

    Code:
    	//THE POINTER PART HERE IS PROBABLY TOTALLY WRONG
    
            printf("Enter empoyee you want to inspect: \n");
    
                                   // this bit has to point to the chosen employee in the employee array.  Make use of the index
                                   scanf("%d", &emp_ptr[d].emp_index); // scans the index value desired
                                   for (d = 1; d <= emp_num; d++) {//this is the ammount of employees to output on the screen.
                                       ptr = &emp_ptr[d];//This is the pointer decared above. ptr points now to the employee of index  d, that is, emp_ptr[d]
                                   }
                                        printf("Employee summary: %p \n", ptr);//Prints desired employee
    As it is right now it is not working.... Can anyone help?
    Last edited by bluetxxth; 02-24-2010 at 07:27 AM. Reason: edit

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    You've got the right idea, but remember arrays are indexed starting from 0:
    Code:
    for (d = 1; d <= emp_num; d++) {
    And so the last index is one less than the total number (eg, 10 elements are indexed 0-9).
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User bluetxxth's Avatar
    Join Date
    Feb 2010
    Location
    sweden
    Posts
    43

    Pointer to structure problem

    Quote Originally Posted by MK27 View Post
    You've got the right idea, but remember arrays are indexed starting from 0:
    Code:
    for (d = 1; d <= emp_num; d++) {
    And so the last index is one less than the total number (eg, 10 elements are indexed 0-9).
    Hi MK,

    Having changed initial value in the for loop to d=0, now I get a memory location as an outptut for the pointer

    Code:
     printf("Employee summary: %p \n", ptr);//Prints desired employee
    the output of this is now '004050F0' and not the desired employee, the one I choose on at

    Code:
    scanf("%d", &emp_ptr[d].emp_index);


    What can possibly be wrong?

    Thank you

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by bluetxxth View Post
    Having changed initial value in the for loop to d=0, now I get a memory location as an outptut for the pointer
    That's what %p does -- it prints the memory address in a pointer. It's only useful for debugging and not for "normal" output.

    You want to do something more like:
    Code:
    printf("Employee summary\nName: %s\nAge: %d\n",ptr->name,ptr-age);
    I think you are a little confused about something here:
    Code:
    truct employee {
        int emp_index; //To assign a value to each employee for a later "pointing"
        char name[30];
    Kind of hard for me to see what purpose this serves.

    A more serious problem:
    Code:
     void *ptr = &emp_ptr[d]; // here ptr points at the address of the array of employees
        ptr = malloc(sizeof (struct employee) * d); // memory allocation for the previous line - is this right?
    First, you have ptr pointing to a member of emp_ptr (which this is a bad name, it should be "emp_struct" or "emp_rec" or just "employee" -- it is not a ptr). Okay. But every time you do this:

    ptr =

    You are reassigning the ptr. Meaning it is no longer assigned (=) to whatever it was previously. So the initial assignment to &emp_ptr[d] is meaningless.

    Even worse, then you do this:
    Code:
    ptr = &emp_ptr[d];
    I can see why, and that is okay in itself, but you just assigned ptr some memory with malloc! Guess what happens to that: it still exists and is reserved, but you have no pointer to it anymore, because ptr now points to (=) something else. That is called a memory leak because that malloc'd memory is now unusable, and cannot be freed. You have no way to refer to it.

    So for sure get rid of that malloc call. I don't think you need a seperate "ptr" at all.

    AFAICT, all you need to do here is this:

    - you have your array, emp_ptr.
    - ask for a record number and put that into a seperate, stand-alone int (d)
    - now show emp_ptr[d]

    So, no need for:
    1) emp_ptr.emp_index
    2) ptr
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User bluetxxth's Avatar
    Join Date
    Feb 2010
    Location
    sweden
    Posts
    43

    pointer to structure problem

    Hi Mk,

    Thank you for the explanation!!


    Aside of the bad name for the variabe, which I have changed as you suggested...



    The reason for the int emp_index; variable within the structure is because I thought it would be helpful for pointer purposes.

    Code:
    struct employee {
        int emp_index; //To assign a value to each employee for a later "pointing"
        char name[30];
        char address[100];
        int age;
        float salary;
    } emp_struct[N];
    My objective is to make an list of employees with the use of an array and to use dynamic memory allocation for it, I thought of being able to enter each employee with a different int emp_index by accepting input from the user with scanf in that way I could setup an array of employees in a dissorganize manner. For example, with int emp_index =7, int emp_index = 6, int emp_index = 2, int emp_index = 15... and so on and then being able to call them back. The reason why entering them in a disorganized way is to provide for the oportunity to test sorting in this program. Sorting by employee number that is, alghough I thought to expand the functionality to make it possible to sort according to different criteria such as name, age etc..

    In addition to this I thought about the int emp_index variable because I want to be able to recall the whole employee not just a value within an employee with the help of pointers. In other words I thought that having a pointer pointing to the int emp_index would return the employee I wanted...

    Lastly with the malloc what I was trying to do is to reserve memory for the array..

    Do you think this approach would work?

    Thnx,

    Bluetxxth

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Okay. If I follow what you are saying, having that unique ID will allow you to identify a specific record without having to identify on the basis of (for example) name, which you could have two records with the same name on it. That is a very good idea -- many (probably most) databases do this.

    It also frees you from depending on the array index, which could change if you sort the list.

    However, having a "pointer to this" needs some further thought. Where are these pointers going to be stored? And why not just use a pointer to the struct itself? You know you can do that, right?

    Code:
    struct employee *ptr = &emp_struct[x];
    where x could be any one of the structs.

    There's a complication with this pointer indexing scheme tho: when you sort an array, the elements are rearranged in physical memory too. So a pointer to emp_struct[5] will still point to emp_struct[5] (or any member there of -- same idea) even if the content is different because of sorting the array.

    This is one reason linked lists are useful -- but lets stick with the array for a minute.

    What you can do here is have an array of struct pointers parallel to the struct array:
    Code:
    struct employee *emp_ptrs[N];
    However, the parallelism will not be emp_ptrs[1] = &emp_struct[1] (tho it could). Every time you create a record, give it a unique new number (make them sequential starting from 0) for emp_index. Then, set that element of emp_ptrs to the emp_struct with that emp_index:
    Code:
    emp_ptrs[emp_struct[d].index] = &emp_struct[d];
    So here d is any one of them. "d" does not have to equal "emp_struct.index", since if you sort the struct array the array index (but not emp_index) will change.

    Whenever you do that, you reset the appropriate emp_ptrs[]. This way, you can use the pointer array to access specific records. emp_ptrs[5] will alway point to the record where emp_index == 5.
    Last edited by MK27; 02-24-2010 at 12:23 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User bluetxxth's Avatar
    Join Date
    Feb 2010
    Location
    sweden
    Posts
    43
    Hi MK,

    One more time, thank you so much for the explanation! What I thought of was what you describe I think, or at least like it, in that I wanted to have it as a unique ID and also in order to be independent from the array index.

    As a matter of fact, at the very least it crossed my mind that the pointer should point to the struct itself that was probably the reason I had that bad name before 'emp_ptr[N];

    I also have besides me a notebook in which I drew two arrays one for the id and another one for a 'number' but I could not come up with the exact function of the second array, the number of what??

    I believe you have enligthened me with the right approach for what I wanted to do, this of course requires some testing and some thought... so I will try to implement it and if you don't mind get back to you with any problems ;-)

    Lastly, now that you mention the Linked lists I wanted to say that eventually I want to implement a list as an array and a list as a linked list, but this is the first thing I wanted to try.



    BR,

    Bluetxxth
    Last edited by bluetxxth; 02-24-2010 at 11:51 PM.

  8. #8
    Registered User bluetxxth's Avatar
    Join Date
    Feb 2010
    Location
    sweden
    Posts
    43

    pointer to structure problem

    HI there MK,

    I have been trying to implement what you suggested yesterday but I still have problems.



    Based on this structure:

    Code:
    struct employee {
        int emp_index; //To assign a value to each employee for a later "pointing"
        char name[30];
        char address[100];
        int age;
        float salary;
    } emp_struct[N];

    First I made two functions one to make take input from the user to decide the size of the staff

    Code:
    // Takes imput that establishes the size of the staff
    void staff_size() {
        printf("What is the size of your staff?: ");
        scanf("%d", &emp_num);
    }

    Second I fill the staff like this (I think this will be the array of structures):


    Code:
    //Fills staff with desired size of elements - This is the array of structures (emp_struct)
    void staff_create() {
    
        printf("Populating staff......... \n\n");
        for (d = 1; d <= emp_num; d++)
            emp_struct[emp_num];
    
    
    }

    Then I thought to make another function for the array of pointers like this:

    Code:
    // This is an array of pointers. As an index it will have the index value of the array of structures
    void fill_emp_struct(void *emp_ptrs, struct employee emp_struct) {
    
        for (d = 0; d <= emp_num; d++)
            emp_ptrs[emp_struct[d].emp_index] = &emp_struct[d];
    
    }

    This above, however, gives me an error which says;

    'main.cpp:52: error: no match for 'operator[]' in 'emp_struct[d]''

    I don't even think its necessary but I thought that perhaps I could make the function return an employee and call it within the main function instead of coding there... what do you think?


    Below within the main function I have:

    Code:
        struct employee *ptr = &emp_struct[d]; // Used for an array of structures. Here ptr points at the address of emp_struct
        struct employee * emp_ptrs[N]; //Declares a pointer of type employee which will be used for the array of pointers.
        emp_ptrs[emp_struct[d].emp_index] = &emp_struct[d]; //Initializes the pointer above, emp_ptrs will have as index, emp_index
        // emp_ptrs will be pointing to &emp_stuct[d]
    I think this time I decared and initialized the pointers correctly...


    Then, I think this is my second probem, I believe I did not understand how to printf, or 'extract' if you will, the contents of the pointer that points to the &emp_struct[d].emp_index which is theoretically the employee I have scanf'ed and the one I want to view.

    Code:
     printf("Enter empoyee you want to inspect: \n");
                                   // this bit has to point to the chosen employee in the employee array. Make use of the index
                                   scanf("%d", &emp_struct[d].emp_index); // scans the index value desired
                                   for (d = 0; d <= emp_num; d++) {//this is the ammount of employees to output on the screen.
                                   }
                                       printf("Employee summary: %d\n", ptr -> &emp_struct[d].emp_index);//Prints desired employee << HERE IS THE PROBLEM

    for the code above I get this error: main.cpp:177: error: expected unqualified-id before '&' token


    What is I do wrong? Can u give me some more ideas?

  9. #9
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    It's hard for me to figure out how all this code relates without seeing the whole thing, because I suspect there are some simple but fundemental flaws/misconceptualizations involved.

    Anyway, if the number of employees/records is going to be variable, you are best off using a "dynamic" array of structs. That just means having a pointer, and malloc'ing enough space for it.

    It also means you will have to do the same thing with the pointer array. So here's a sort of demo that includes malloc'ing the array:
    Code:
    #include <stdio.h>
    #include <stdlib.h>		/* for malloc */
    #include <string.h>
    
    typedef struct {     /* typedef saves having to use "struct" identifier all the time */
    	int ID;
    	char name[64];
    } employee_record;
    
    int main() {
    	int n;
    	employee_record *empRecs; 
    	employee_record **empIDs;
    
    	printf("Enter the number of employees: ");
    	scanf("%d%*c",&n);
    	if (!(empRecs = malloc(sizeof(employee_record)*n)) 
    			|| !(empIDs = malloc(sizeof(employee_record*)*n))) {
    		puts("Not enough memory!");
    		return -1;
    	}
    
    
    	/* example of creating a new record */
    	n = 0;
    	empRecs[n].ID = n;
    	strcpy(empRecs[n].name,"mk27");
    	empIDs[empRecs[n].ID] = &empRecs[n];
    
    	/* using the index pointer array */
    	printf("ID: %d Name: %s\n", empIDs[0]->ID, empIDs[0]->name);
    
    	/* for good form */
    	free(empRecs);
    	free(empIDs);
    
    	return 0;
    }
    In the example, the ID and the index in both arrays is still the same as no rearrangements have occurred yet. Notice you must use "indirect notation" with the pointer to the struct:

    Code:
    empRecs[x].name;   // direct notation
    empIDs[x]->name; // indirect
    Also notice the subtle difference between the two red expressions. The first one is space for an actual struct (employee_record), the second one is for a pointer to a struct (employee_record*). This is why empIDs is declared "**empIDs" -- it is a pointer to pointer(s). Maybe empIndex would be a better name for empIDs...

    ps. yes, I live in "that" Queens -- right at the end of the north fork of the Rockaway A-line (pretty sure it was you that asked).
    Last edited by MK27; 02-25-2010 at 02:03 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  10. #10
    Registered User bluetxxth's Avatar
    Join Date
    Feb 2010
    Location
    sweden
    Posts
    43

    Wink problem with pointer to structure

    Hi MK,

    Thank you for the explanation it was very thorough.

    I think my problems biggest problems are the pointers and the malloc; specially the latter.

    I will give your suggestions a try and then probably post the program. I donīt mind sharing, it was just an experiment I made for learning purposes and it has no use beyond that. I sent you a private message but I donīt think it went through.


    Cheers,

    Bluetxxth

    Ps. The Queens you live in is the same as the one I used to live in ...at the end of the N train in Ditmars Blv.
    Last edited by bluetxxth; 02-25-2010 at 04:57 PM. Reason: re-word

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. problem accessing a value in a structure
    By buetxxth in forum C Programming
    Replies: 6
    Last Post: 02-11-2010, 12:30 PM
  2. problem with structure !!!!
    By m_kaleia in forum C Programming
    Replies: 2
    Last Post: 04-19-2009, 06:41 AM
  3. Problem with arrays inside a structure
    By babu in forum C Programming
    Replies: 4
    Last Post: 07-12-2007, 09:35 AM
  4. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  5. Problem checking for numeric value in a structure
    By ronkane in forum C++ Programming
    Replies: 4
    Last Post: 01-20-2002, 02:53 PM