Ordo
Ordo

Reputation: 705

Pointing to an element of a struct

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

Answers (3)

sje397
sje397

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

Luca Matteis
Luca Matteis

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

D&#233;j&#224; vu
D&#233;j&#224; vu

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

Related Questions