【问题标题】:Allocate struct from function in C从C中的函数分配结构
【发布时间】:2011-02-06 03:11:11
【问题描述】:

我在编写一个在 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 */

关于如何实现这一点的任何建议?

【问题讨论】:

  • 我认为如果你能多描述一下这个函数的使用方式以及你想对创建的结构做什么,那将会很有帮助。如何在 C 中分配内存和创建数据结构很大程度上取决于您计划如何使用它们。

标签: c function struct


【解决方案1】:

您当前代码的问题是您创建的结构是在堆栈上创建的,并且会在函数返回后立即清理。

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++点。)

【讨论】:

    【解决方案2】:

    你必须返回一个通过 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) 点的建议...只要 NAME_SIZE 是一个合理的大小,那么做正确的事情并不值得 - 动态分配内存和必须管理它。无需将其复杂化。
    • 如果保持简单对您很重要,那么您就知道该怎么做了。但是,将 200 字节分配给只需要 5 个字节的东西是多余的(而将 5 个字节分配给需要 6 个字节的东西是一个错误) - 因此您可能想要使用指针
    • 确保你在完成后free结构,否则你会有内存泄漏。
    【解决方案3】:
    1. 为什么 make Employee 返回无效?您需要从 make_employee 函数中返回 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()员工!

    【讨论】:

      【解决方案4】:
      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;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-23
        • 2020-02-02
        • 1970-01-01
        • 2011-06-02
        • 2012-06-08
        • 1970-01-01
        • 1970-01-01
        • 2017-04-24
        相关资源
        最近更新 更多