Выделить структуру из функции в C - PullRequest
2 голосов
/ 06 февраля 2011

У меня проблемы с написанием функции, которая выделяет структуру в C. В идеале, я хочу, чтобы функция заполняла поля структуры параметрами, переданными в нее.

Я определил структуру в моем заголовочном файле следующим образом:

typedef struct {
  char name[NAME_SIZE]; //Employee name
  int birthyear; //Employee birthyear
  int startyear; //Employee start year
} Employee;

И вот что у меня есть для моей функции в настоящее время:

void make_employee(char _name, int birth_year, int start_year) {
  Employee _name  = {_name,birth_year,start_year}; //allocates struct with name
} /* end make_employee function */

Какой-нибудь совет, как этого добиться?

Ответы [ 4 ]

6 голосов
/ 06 февраля 2011

Проблема с вашим текущим кодом состоит в том, что создаваемая вами структура создается в стеке и будет очищена, как только функция вернется.

struct foo
{
    int a;
    int b;
};

struct foo* create_foo( int a, int b )
{
    struct foo* newFoo = (struct foo*)malloc( sizeof( struct foo ) );
    if( newFoo )
    {
        newFoo->a = a;
        newFoo->b = b;
    }
    return newFoo;
}

Это даст вам выделенный объект кучи.Конечно, вам понадобится функция для освобождения этой памяти, или это утечка памяти.

void destroy_foo( struct foo* obj )
{
    if( obj )
        free( obj );
}

void print_foo( struct foo* obj )
{
    if( obj )
    {
        printf("foo->a = %d\n",obj->a);
        printf("foo->b = %d\n",obj->b);
    }
}

(кстати, этот стиль поможет вам частично перейти к «объектно-ориентированному» C. Добавьте несколькоуказатели на структуру (чтобы получить полиморфное поведение), и у вас есть кое-что интересное, хотя я бы поспорил с C ++ на этом этапе.)

3 голосов
/ 06 февраля 2011

Вы должны вернуть указатель, выделенный через malloc:

Employee* new_employee(char *_name, int birth_year, int start_year) {
    struct Employee* ret = (struct Employee*)malloc(sizeof(struct Employee));
    ret->name = _name;
    ret->birth_year = birth_year;
    ret->start_year = start_year;
    return ret;
}

еще две вещи: (1) вам следует сделать определение структуры имени char* вместо char[NAME_SIZE].Выделение массива char делает структуру намного больше и менее гибкой.Все, что вам действительно нужно, это char* в любом случае.И (2) изменить определение функции на char*.

1 голос
/ 06 февраля 2011
  1. Почему возврат сотрудника становится недействительным? Вам нужно вернуть Employee из функции make_employee!

  2. У вас проблемы с компилятором, который жалуется на синтаксис x = {a,...}? Тогда напишите это так: Emp e; e.field1 = a; ...

  3. У вас странные проблемы с перезаписью / фиктивными числами? Если вы выделите структуру в функции, она станет недействительной (и склонной к перезаписи), как только функция вернется! Чтобы обойти это, вы должны:

    • Вернуть копию структуры (это нормально для небольших структур):

      Employee make_emp(int a){
          Emp emp; //Allocate temporary struct
          emp.filed1 = a; //Initialize fields;
          return emp; // Return a copy
      }
      
    • Вместо этого выделите структуру в куче и обрабатывайте ее с помощью ссылок (т. Е. Указателей):

       Employee* make_emp(int a){
          Emp* emp = malloc(sizeof(Emp)); //Allocate the struct on the heap
                                          //And get a reference to it
          emp->filed1 = a; //Initialize it
          return emp; //Return the reference
       }
      

      Не забудьте free() Сотрудника после того, как вы закончите с ним в этом случае!

1 голос
/ 06 февраля 2011
Employee * make_employee(char *_name, int birth_year, int start_year)
{
    Employee *employee;

    if (employee = (struct Employee *)memalloc(sizeof(Employee)) == NULL)
    {
        return NULL;
    }
    else
    {
        strcpy(&(employee->name), _name);
        employee->birthyear = birth_year;
        employee->startyear = start_year;
        return employee;
    }
}
...