2011-02-06 13 views
1

Cで構造体を割り当てる関数の作成に問題があります。理想的には、渡されたパラメータで構造体のフィールドに関数を埋めたいと思います。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 */ 

これを実現する方法上の任意のアドバイスはありますか?

+2

は、私はあなたが作成した構造体でやりたいどのようにこの機能が使用され、どのようにもう少し説明することができれば、それは参考になると思います。 Cでメモリーを割り振り、データ構造を作成する方法は、どのように使用するかによって大きく異なります。 – linuxuser27

答えて

1

あなたはmalloc関数経由で割り当てられたポインタを返すことがあります。 char配列を割り当てることで、構造体がはるかに大きく柔軟性が低くなります。あなたが本当に必要とするのは、とにかくchar*です。そして、(2)関数定義をchar*に変更する。

+0

ポイント(1)のアドバイスについては分かりません。「NAME_SIZE」が妥当なサイズであれば、メモリを動的に割り当てて管理する必要はありません。必要以上に複雑にする必要はありません。 –

+0

物事を単純なものにすることが重要である場合、あなたは何をすべきかを知っています。しかし、5バイトしか必要としないものに200バイトを割り当てることは、過剰なものです(6を必要とするものに5を割り当てることはバグです) - なぜポインタを使うべきなのでしょうか? – kelloti

+0

あなたは、そうしないと、メモリリークが発生します。 –

5

現在のコードの問題は、作成した構造体がスタックに作成され、関数が返されるとすぐにクリーンアップされることです。

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.への道の一部を取得し、ポリモーフィック動作を取得する(構造体にいくつかの関数ポインタを追加)し、あなたが何か面白いものを持って、私は主張したいのに。

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; 
} 

2以上のもの:(1)あなたが名前char*代わりchar[NAME_SIZE]のの構造体の定義を行う必要があり、その点でのC++用)

1
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; 
    } 
} 
1
  1. なぜメイク従業員のリターンは無効にしますか?あなたはmake_employee関数からEmployeeを返す必要があります!

  2. x = {a,...}の構文について不平を言うコンパイラに問題がありますか?遠くに書いてください:Emp e; e.field1 = a; ...

  3. 奇妙な上書き/偽数の問題がありますか?関数に構造体を割り当てると、関数が返るとすぐに無効になり(上書きされる傾向があります)!これを一周するには、あなたのいずれかを持っている:

    • 戻り構造体のコピー(これは小さな構造体のためにOKです):

      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()に従業員を忘れないでください!

関連する問題