2017-12-10 9 views
-1

だから私はこの構造体をパーサのツリーとして使用しています。構造体に含まれる文字列ポインタをコピーする問題

struct Expr{ 
    struct Expr* a; 
    char* value; 
    struct Expr* b; 
}; 

このようにmallocで初期化します。

Expr* initExp(){ 
    Expr* ret; 
    ret = (Expr*)malloc(sizeof(Expr)); 
    ret->a = (Expr*)malloc(sizeof(Expr)); 
    ret->b = (Expr*)malloc(sizeof(Expr)); 
    ret->value = (char*)malloc(sizeof(char)); 
    ret->value = "18killstreak"; 
    ret->a->value = "18killstreak"; 
    ret->b->value = "18killstreak"; 
    return ret; 
} 

これまでのデバッグやツリーの印刷で必要だった以上の機能をここに書いています。 私はこのようにExpr * a->値をExpr *値にコピーしようとしています。

strcpy(temp2->value,ret->a->value); 

これらの値は、それぞれ「18killstreak」と「x」です。 しかし私のプログラムはこの行でクラッシュし、私はこの時点で他の多くの戦術を試しました。

+0

typedefで構造体を定義しましたか?そうでなければ、Exprだけでなく、 "struct Expr"を使う必要があります。 –

+0

はい私はtypedef構造体Expr Exprを持っています。ファイルの先頭に –

答えて

1

問題は、文字列のmemeoryを管理していないため、ただstrcpyを使うことができないということです。たとえば、あなたが持っているとき:

ret->value = (char*)malloc(sizeof(char)); 
ret->value = "18killstreak"; 

これは、長さ0の文字列(ちょうどNUL)のためのスペースをallocats、その後、(メモリリークを)それを捨て、静的にポインタで割り当てられたポインタを上書き定数文字列"18Killstreak"。後で静的定数文字列(strcpy)を上書きしようとするとクラッシュします。

正しくするには、文字列のメモリを割り当てて管理する必要があります。これを行う最も簡単な方法は、それぞれに文字列のメモリを所有させ、そのメモリを割り当て/コピー/解放するのにstrdup/freeを適切に使用することです。だからあなたのinit関数は次のようになります。

Expr* ret; 
ret = (Expr*)malloc(sizeof(Expr)); 
ret->a = (Expr*)malloc(sizeof(Expr)); 
ret->b = (Expr*)malloc(sizeof(Expr)); 
ret->value = strdup("18killstreak"); 
ret->a->value = strdup("18killstreak"); 
ret->b->value = strdup("18killstreak"); 

後で、構造体のvalueを交換したいとき、あなたは:

free(temp2->value); 
temp2->value = strdup(ret->a->value); 

、あなたがExprを解放したい場合、あなたはにも(最初に必要)valueを解放:

free(exp->value); 
free(exp); 

さてこれで1 isuueはstrdupは、標準C関数ではないということです - それはPOSIX functiですに。したがって、POSIXシステム(LinuxやOSXなど)では利用可能ですが、POSIX以外のシステムでは利用できません。したがって、あなた自身で定義する必要があります:

char *strdup(const char *str) { 
    char *rv = malloc(strlen(str) + 1); 
    if (rv) strcpy(rv, str); 
    return rv; 
} 
+0

はい!あなたはstrcpyの前にメモリを割り当てる必要があります。そうでない場合は、メモリ侵攻 –

+0

これは非常に役に立ちました。ありがとうございました! –

関連する問題