2016-04-07 14 views
1

Cでローカル配列を含む構造体を返すことは有効ですか?例えばCでローカルポインタを含む構造体を返す

// Define a string type 
typedef struct { 
    char* c_str; 
} string; 

// Function to append 2 strings 
string string_append(string str1, const string str2) { 

    // Create a local array 
    char buffer[strlen(str1.c_str) + strlen(str2.c_str) + 1]; 

    strcpy(buffer, str1.c_str); 
    strcat(buffer, str2.c_str); 

    // Store a pointer to the local array in a struct 
    string ret = { buffer }; 

    return ret; 
} 

int main(int argc, char* argv[]) { 

    string str1 = { "hello" }; 
    string str2 = { "goodbye" }; 
    string str3 = string_append(str1, str2); 
} 

str3の内容はstring_appendを実行した後に有効になりますか?

+0

構造体に**配列が含まれていない**:ポインタが含まれています。配列とポインタの違いについては、[c-faq](http://c-faq.com)のセクション6を参照してください。 – maraguida

+0

質問を明確にします。私が尋ねるのは、構造体が指す配列の内容が危険にさらされるということですか? – tjwrona1992

+2

これらは有効ではありません。あなたはこれをすることはできません。 –

答えて

1

コメントに記載されているとおり、これはできません。しかしなぜ

答えはあなたのコード

char buffer[strlen(str1.c_str) + strlen(str2.c_str) + 1]; 

が、それはまた、関数の戻りアドレスを含むスタック、および引数の一部として作成されています、と言うことです自動ストレージを、配分されていることです。だから、あなたが関数から戻ってきたとき、あなたがそれを使ってみるまでに割り当てられたスペースが壊れているかもしれませんし、そうでないかもしれません。

2

関数が戻ると、bufferの内容は未定義です。関数の外に存在する可能性がある関数内に何かを作成したい場合は、malloc(またはそれと同等のもの)で割り当てる必要があります。

+0

もし私がmallocを使って割り当てた変数を返すと、私の関数を使っている誰もが解放される必要があることを簡単に確認できますか? – tjwrona1992

+0

@ tjwrona1992:うまく書かれた文書を提供することによって。 – alk

+0

@alk:私はまだ関数からmallocされた変数を返すのは、経験の浅い開発者の中にはメモリリークが起こるのを待っているような気がします。 – tjwrona1992

0

buffer文字配列が関数内に作成されます。関数内で作成される変数のデフォルトのストレージクラスはAutomaticです。

つまり、変数はスタックの一部として作成されます。しかし、関数が返って制御が呼び出し関数に向かうと、呼び出し関数が別の関数を呼び出すとすぐにそのスタックが修正されます。たとえば、string_append()機能の後にprintf()を呼び出したとします。 printf()用に作成されたスタックは、char *c_str pointer of string str3が指し示す位置を上書きします。そして、いくつかのゴミ値を表示します。

お試しください。

関連する問題