2017-06-28 6 views
-1
#include <stdio.h> 
#include <stdlib.h> 
#include <stdbool.h> 
#include <string.h> 

typedef struct _person 
{ 
    char *fname; 
    char *lname; 
    bool isavailable; 
}Person; 


Person *getPersonInstance(void) 
{ 
    Person *newPerson = (Person*) malloc(sizeof(Person)); 
    if(newPerson == NULL) 
     return NULL; 
    return newPerson; 
} 

void initializePerson(Person *person, char *fname, char *lname, bool isavailable) 
{ 
    person->fname = (char*) malloc(strlen(fname)+1); 
    /*problematic behaviour if i write: person->fname = (char*) malloc (sizeof(strlen(fname)+1)); */ 

    person->lname = (char*) malloc(strlen(lname)+1); 
/*problematic behaviour if i write: person->lname = (char*) malloc (sizeof(strlen(lname)+1)); */ 

    strcpy(person->fname,fname); 
    strcpy(person->lname,lname); 
    person->isavailable = isavailable; 

    return; 

} 

// test code sample 
int main(void) 
{ 
    Person *p1 =getPersonInstance(); 
    if(p1 != NULL) 
     initializePerson(p1, "Bronze", "Medal", 1); 

    Person *p2 =getPersonInstance(); 
    if(p2 != NULL) 
     initializePerson(p2, "Silver", "Medalion", 1); 

    Person *p3 =getPersonInstance(); 
    if(p3 != NULL) 
     initializePerson(p3, "Golden", "Section", 1); 

    printf("item1=> %10s, %10s, %4u\n",p1->fname, p1->lname, p1->isavailable); 
    printf("item2=> %10s, %10s, %4u\n",p2->fname, p2->lname, p2->isavailable); 
    printf("item3=> %10s, %10s, %4u\n",p3->fname, p3->lname, p3->isavailable); 

    return 0; 
} 

インサイドinitializePersonは()私が使用している場合:私はテストするときmalloc、sizeof、strlen関数は可能ですか?

person->fname = (char*) malloc (sizeof(strlen(fname)+1)); 
person->lname = (char*) malloc (sizeof(strlen(lname)+1)); 

は、これら2つのコードラインは、私は上記のソースコード内で使用していたものの代わりに有効になっていると、私は実行時エラーを取得する可能性がありますCodeBlocks IDEを使用してコードを作成します。コンソールがフリーズして動作を停止する可能性が非常に高い。 ubuntu端末を使ってコードをテストすると、入力データのサイズにかかわらず問題なくいつでも動作します。

質問:(前の段落の2つのコードを使用していると仮定します)sizeof countsバイトを知っていて、strlenはヌルを見つけるまで文字数を数えます...しかしsizeofとstrlen malloc()内で一緒に使用されると、バックグラウンドで競合が発生しますか?問題であると想定されるのは?なぜコードはそのような不安定で信頼性の低い動作をしていますか?どうして?

+0

は、[結果をキャストしないでください 'malloc'でC](http://stackoverflow.com/q/605845/995714) –

+0

なぜだろうの*サイズ*長さは実際の長さの*値*と同じですか? –

+0

ところで、文字列のメモリを割り当てて別の文字列からコピーする必要がある場合は、 'strlen'、' malloc'、 'strcpy'の3つの関数を組み合わせた' strdup'を使う方が簡単です。 – Eugene

答えて

4

sizeofは、引数の格納サイズ(型の式でもよいし、型自体でもよい)を評価します。

strlen(fname)+1 

これはタイプsize_tの表現である:だから、引数がここにあるものをよく見て。 sizeofは、size_t(おそらく4または8のいずれか)を格納するために必要なバイト数を指定します。

あなたはがほしいと思っていますはあなたの文字列のための十分なストレージなので、strlen()のバージョンは正しいものです。それ以外の場合は、4バイトまたは8バイトの空き領域を確保し、割り当てられていないメモリ位置に書き込みます。 - >未定義の動作。サイドノートでは


void *のキャストは明示的にCで必要とされないし、多くの(すべてではない)Cコーダによっては悪い習慣と考えられています。 this classic quesionを参照してください。

5

sizeof(strlen(fname)+1)は意味をなさない。結果の型のサイズはstrlenです。これは4バイトの整数です。だからあなたはあまりにも少ないメモリを割り当てることになります。

使用この:

person->fname = malloc(strlen(fname)+1); 
関連する問題