2016-11-27 7 views
1

構造体を初期化して戻り値に戻す関数を作成しようとしていますが、動作させることができません。私はどこで間違いを犯したのですか?セグメント化エラーが発生しました。私はミスをしなかった関数の戻り値でC構造体を初期化する

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

typedef struct { 
    int id; 
    char *name; 
} Object; 

Object object_ctor(int id, char *name); 

int main() 
{ 
    Object x; 

    x = object_ctor(1, "Alex"); 

    printf("%s\n", x.name); 
    return 0; 
} 

Object object_ctor(int id, char *name) 
{ 
    Object y; 
    y.id = id; 
    y.name = *name; 

    return y; 
} 
+0

Yはスタックにローカルです。関数が終了すると消えます。ヒープを使用する必要があります – OldProgrammer

+0

'object_ctor'の名前を逆参照しています。それをしないでください。 'strdup(name)'やそれに類するものを使用して、ヒープで割り当てられたバージョンの文字列を持つこともできますが、異なる関数から 'object_ctor'を呼び出すと、ポインタはおそらく割り当てられた文字列を指している可能性がありますスタック(すなわち、もはや存在しない)。 – Goodies

+3

@OldProgrammer:構造体などのローカル変数を(コピーして)返すことは完全に許可されています。許容されないのは、ローカル変数へのポインタを返すことです。関数が 'Object *'を返した場合、あなたの心配は正当なものになります。 –

答えて

2

これはラインです:

y.name = *name; 

それが理由のカップルのために間違っています。

  1. あなたはタイプchar*y.nameの変数に、char、​​を割り当てています。ポインタの代入演算子の制約に違反します。 C11標準からの

    6.5.16.1単純な割り当て

    制約以下の

    1つは保持しなければならない。

    ...

    - 左のオペランドには、アトミック、修飾、または非修飾ポインタ型があります(左辺オペランドが左辺値変換後に持つ型を考慮して)両方のオペランドは、互換性のある型の修飾バージョンまたは非修飾バージョンへのポインタであり、右に指されている型のすべての修飾子を持つ。

    - 左のオペランドには、アトミック型、修飾型、または非修飾型のポインタ型があります(左辺のオペランドが左辺値変換後に持つ型を考慮して)1つのオペランドはオブジェクト型へのポインタで、もう1つは修飾されたバージョンまたは修飾されていないバージョンvoidであり、左に指されている型は、その型のすべての修飾子を右に指しています。

    - 左のオペランドは、アトミック、修飾、または非修飾ポインタであり、右はNULLポインタ定数です。または

    この割り当てのRHSは、上記の制約を満たしていません。あなたは

    printf("%s\n", x.name); 
    

    にヌル終端文字列としてその値を扱うとき

  2. あなたは未定義の動作に実行します。

このようなエラーは、コンパイラの警告レベルを上げることで検出できます。 gcc -Wallでコンパイルすると次のような結果が得られます。あなたが好きなものを使用する必要が

soc.c: In function ‘object_ctor’: 
soc.c:26:12: warning: assignment makes pointer from integer without a cast [-Wint-conversion] 
    y.name = *name; 
      ^

y.name = strdup(name); 

strdupは、ご使用のプラットフォーム上で利用できない場合、それは実装するにはあまりにも難しいことではありません。ウェブ上で簡単に実装を見つけることもできます。

+0

'strdup()'は通常、 'malloc()'を使用します。つまり、解放する必要があります。おそらく、 'object_dtor'関数は、' strdup() 'から割り当てられたメモリを' free() 'することができます。 – Goodies

+0

ありがとう、私のために働く:) – Zeusko

+0

私もこれを試した:y.name =名前;それがうまくいって、それはどうやって可能ですか? – Zeusko

関連する問題