Reputation: 705
I want to use the following code to copy the user input into a struct on the heap. I know it is incomplete but that's unimportant for my question.
#include "7.1.h"
#include <stdio.h>
#include <stdlib.h>
int main ()
{
struct Employee emp;
struct Employees* emps[3];
for ( int i = 1; i < 2; i ++)
{
printf("Please type in the emplooyes data./n Firstname:");
scanf("%s", emp.first);
printf("Please type in the emplooyes data./n Lastname:");
scanf("%s", emp.last);
printf("Please type in the emplooyes data./n Title:");
scanf("%s", emp.title);
printf("Please type in the emplooyes data./n Salary:");
scanf("%d", emp.salary);
emps[i] = createEmployee(char*, char*, char*, int);
}
}
My question concerns the codepiece emps[i] = createEmployee(char*, char*, char*, int);
. I don't know how to give the function createEmployee()
the values of the struct Employee emp;
as pointers. I know that's not necessary but i want to do it that way. I would be thankful for any advise.
Upvotes: 1
Views: 1140
Reputation: 41862
This should do it:
emps[i] = createEmployee(emp.first, emp.last, emp.title, emp.salary);
...but if you changed your function a little, it would be a lot better to use:
emps[i] = createEmployee(emp);
Your Employee
structure could be defined like so:
struct Employee {
char first[256];
//...
};
...in which case 'first' is an array. Or, it could be defined as
struct Employee {
char *first;
// ...
};
An array of chars and a pointer to a char are very similar beasts. But in the first case, you will automatically allocate 256 chars for the first name each time you create an Employee
. In the second case, you have to allocate the memory manually, and duplicate it appropriately when copying, and remember to delete it as well.
Say your createEmployee
method looks like:
Employee *createEmployee(char * first, char * last, char * title, int salary);
If you take the first form of the Employee
struct above, you might do:
struct Employee *createEmployee(char * first, char * last, char * title, int salary) {
struct Employee *retVal = (struct Employee *)malloc(sizeof(struct Employee));
strcpy(retVal->first, first);
strcpy(retVal->last, last);
// etc
return retVal;
}
In the second case, you might do:
struct Employee *createEmployee(char * first, char * last, char * title, int salary) {
struct Employee *retVal = (struct Employee *)malloc(sizeof(struct Employee));
retVal->first = strdup(first);
retVal->last = strdup(last);
// etc
return retVal;
}
Note that the second case makes deleting (and copying) quite tricky.
void deleteEmployee(struct Employee *emp) {
free(emp->first);
free(emp->last);
// etc
free(emp);
}
...but for the first form, you just have to free(emp)
.
Upvotes: 2
Reputation: 29267
This should work:
emps[i] = createEmployee(emp.first, emp.last, emp.title, emp.salary);
You must consider that the emp
data structure is local to your function (for this case main
). This might lead to very weird errors if you're using emp
anywhere else, because the data allocated for emp
will be gone once the function returns - so using any data from emp, such as emp.first
and emp.last
, might cause some issues.
One way to solve this would be to also allocate emp
dynamically, and pass a reference of it anywhere you want - this is usually how it's done.
Another quick hacky way would be to dynamically allocate the stuff that will be lost, such as your pointers:
emps[i] = createEmployee(strdup(emp.first), strdup(emp.last), strdup(emp.title), emp.salary);
strdup() will duplicate the string you give it, and it will store it using malloc()
(heap) so it won't be gone when the function returns.
Upvotes: 2
Reputation: 28850
First there is probably a typo in
struct Employees // the s
You could simply pass the emp
record as a pointer
emps[i] = createEmployee( &emp );
And you have to allocate a new structure, that is returned to the caller
struct Employee *createEmployee(struct Employee *p)
{
struct Employee *newe = malloc(sizeof(struct Employee));
memcpy(newe, p, sizeof(struct Employee));
return newe;
}
Assuming the structure contains char [x]
and not char *
.
Not tested.
Upvotes: 0