2016-05-05 10 views
1

私はC言語に新しいので、誰かが私を助けてくれることを願っています。私に文字列があるとします。C言語のポインタを返す

typedef struct String { 
    char *value; 
    int size; 
} String; 

私がしたいことは、この文字列を関数で初期化することです。私の最初の質問は、どんなほうが良いかです。

bool init_String(String **s, char *p) { 
    if (s == NULL || *s == NULL) { 
     return false; 
    } 
    (*s)->value = p; 
    (*s)->size = strlen(p); 
    return true; 
} 

このバージョンでは、関数はポインタへのポインタをとり、その文字列を返しません。私の他のバージョンはこれです:

String *init_String(String **s, char *p) { 
    if (s == NULL) { 
     return NULL; 
    } 
    s->value = p; 
    s->size = strlen(p); 
    return s; 
} 

どちらがユーザーの方がいいですか?私の2番目の質問は、ユーザーに応じて、または私によると、mallocより良いことです。つまり、ユーザーがStringをmallocしてからinit関数に渡すか、init関数がalloc_initとして機能し、mallocの呼び出しと文字列の初期化を行うべきですか?

ありがとうございました

+6

あなたが 'struct'を呼び出すのと同じように、" String "はそれを一つにしません。そして第二の機能は間違っています。 – Olaf

+3

2つめが少なくとも互換性のないポインタ型に関する警告を表示しない場合は、警告レベルを上げる必要があります。または、それは**本当の**コードではなく、実際にはパラメータの 'String * s'を持っています。最後に、 "better"は実際には適用できません。単純な違い( 'String **'と 'String *')は*目的*の根本的な違いを示しているからです。後者( 'String *')は通常、既存の*構造を初期化するために使われます。前者( 'String **')は*ポインタ*を初期化するために使われ、通常はそれ自身の動的割り当てが行われます。 – WhozCraig

+0

関数 'init_string()'のポイントが他の場所に割り当てられた 'struct String'を初期化する場合、その構造体へのポインタへのポインタを渡すポイントはありません。ポインタを構造体に直接渡すと(つまり、 'String **'ではなく 'String *')、関数はその構造体のメンバを更新することができ、それらの更新は呼び出し側に見えるようになります。 –

答えて

3

どうやってですか?

typedef struct String { 
    char *value; 
    size_t size; 
    int ref; // if nonzero, do not free(value) 
} String; 

String refer_String(const char *p) { 
    String out = { p, strlen(p), 1 }; 
    return out; 
} 

String copy_String(const char *p) { 
    String out = { strdup(p), strlen(p), 0 }; 
    return out; 
} 

void free_String(const String *s) { 
    if (!s->ref) { 
    free(s->value); 
    } 
} 

これはあなたの元のコードのように、既存のリテラル文字列を参照する方法を提供するだけでなく、修正することができる新しい文字列を作成する方法。

+0

時にはそれらは便宜的であるかもしれませんが、私はそれらを使っていますが、あなたの 'String.ref'のようなフラグはかなり臭いものです。私はむしろ、与えられた型が指すデータがその型に属するかどうかは不変であると思います。 –

+0

'ref'のポイントは何ですか?単に 'value'を' NULL'に初期化するだけではなく、 'free(NULL);には何も問題ありません。 –

+0

これは内容を使用/変更するときに問題になります。また、 'struct'sを渡すことは問題です。なぜなら、ポインタを渡すと、多くのコピーが必要になり、問題を引き起こすからです。それはハンドルを非常に不快にし、常に内部の意味を念頭に置かなければなりません。 – Olaf

関連する問題