# Thread: poiner to structure problem

1. ## 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];
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?

2. 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).

3. ## Pointer to structure problem

Originally Posted by MK27
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. Originally Posted by bluetxxth
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

5. ## 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];
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. 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.

7. 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

8. ## 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];
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. 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).

10. ## 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.