2017-03-28 6 views
0

私は数週間Cを学習しています。私はmalloc()を使用してヒープ上にいくつかのメモリを割り当てることで私の問題を解決しました。なぜ私のコードが失敗したのかを知っているが、私は100%確実ではない。残念なことに私は自習しているので、インターネット上で親切な人たちに話をしなければなりません。関数間でポインターが渡された後、文字配列が壊れています

アレイを宣言する機能getString()を呼び出しコード記述、作り付けgetchar()を使用してアレイを充填し、その配列へのポインタを返します。

問題私は返されたポインタの値を出力しても問題ありません。しかし、それを単に吐き出して印刷しようとする別の関数に渡すと、文字列の終わりが途切れ、ナンセンス文字が吐き出されることがあります。私は、元の配列がある限りそのCが他のものを保存するためにアレイアドレスでメモリの一部を使用しているのgetString()関数&としてのみ使用されているに起きていると思う何

私の直感は正しいですか?そうでない場合は、誰かがポイント私は正しい方向に?

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

#define MAXLEN 100 

char * getString(void); 
char * doSomethingWith(char *); 

int main(void) 
{ 
    char *string1 = getString(); 
    printf("String: %s\n", string1); 
    char *string2 = doSomethingWith(string1); 
    printf("String: %s\n", string2); // This print out is unreliable! 
    return EXIT_SUCCESS; 
} 

char * getString(void) { 
    int c; 
    char arr[MAXLEN]; 
    char *string = arr; 
    char *cur = arr; 

    while((c = getchar()) != '\n' && c != EOF) { 
     if(cur - string < MAXLEN - 2) { 
      *cur++ = c; 
     } 
    } 
    *cur = '\0'; // Terminate string 

    return string; 
} 

char * doSomethingWith(char *string) { 
    return string; 
} 

これは正しく動作する私の修正されたgetString()です。

char * getString(void) { 
    int c; 
    char *string = malloc(sizeof *string * MAXLEN); 
    char *cur = string; 

    while((c = getchar()) != '\n' && c != EOF) { 
     if(cur - string < MAXLEN - 2) { 
      *cur++ = c; 
     } 
    } 
    *cur = '\0'; // Terminate string 

    return string; 
} 

更新:すべての答えをありがとう!非常に高く評価。

+1

妥当であったスタックコンテキストのスタック上の変数のアドレスを使用しているため、あなたは未定義の動作をしています。私はあなたの質問に 'malloc'を言及してくれるのを嬉しく思っていましたが、コード内のどこにでも使用されているとは思いません。 – paddy

+0

ありがとう!申し訳ありませんが、私はその事実を確認したいので、壊れたコードを投稿しています!私は私の修正で私の答えを更新するつもりです。 – user1803096

答えて

1

getStringは、自動記憶期間を持つ関数ローカル変数のアドレスであるarrのアドレスを返します。関数が返された後にそのアドレス経由でarrにアクセスしようとすると、未定義の動作が発生します。

C規格では、その値を保持する保証はありません。それは保証されません。そのような言語の制約を破るときに、コンパイラが有効なプログラムを生成するという義務はありません。

6.2.4 Storage durations of objects ¶2

オブジェクトの寿命は、ストレージがそれのために予約されることが保証される間、プログラムの実行の一部です。オブジェクトは存在し、一定のアドレスを持ち33)、そのライフタイムを通して最後に格納された値を保持する.34)オブジェクトがその存続期間外に参照された場合、その動作は未定義である。ポインターの値は、それが指し示すオブジェクト(または直前のもの)がその存続期間の終わりに達すると、不確定になります。

上記の寿命は、開き中括弧から閉鎖中括弧getStringまでで、実行中の間のみです。それ以上はない。

+0

ありがとうございました!これは私が起こっていることを理解しているが、私はそれを確認する方法を知らなかった – user1803096

1

char *string = arr;が間違っていますに割り当てられていないため、arrにメモリを割り当てます。これはスタック上の変数です。リターンすると、スタックメモリが解放され、解放された変数へのポインタが返されます。

代わりに、mallocを使用してください。:

string= malloc(strlen(arr)+1); 
strcpy(string,arr); 
return string; 
+0

素晴らしい感謝。それは私が起こっていたと思ったものです! – user1803096

関連する問題