2017-01-06 1 views
-3

ポインタに問題があります。プログラムでは、すべての単語を配列foldersName[]に入れます。私はそれらを印刷するとき、配列内のすべての単語はOKですが、私は配列の1つのポインタの各単語のポインタの配列を返したいと思います。私の方法は:ポインタに関するトラブル - C

char** getTokens(char * path){ 
. 
.//Getting tokens in array foldersName[]; 
.char foldersName[count][255]; 
. 
char * tokens[actualCountOfFolders]; //How much folders in foldersName 
int i; 
for(i=0;i<count;i++){ 
    tokens[i] = foldersName[i]; 
    printf("Folders pointer %s \n",tokens[i]); 
    } 
return tokens; 

たとえば、私はfoldersName = {"C","Game","Halo 4","Map"}です。 しかし、printf tokens[i]の場合は、forループのように、{"C","Game","Halo 4","Map?"}と表示されます。それを修正するには?

関数を呼び出した後、次のコードでこれを行うことはできますか?

char ** tokens =(char **) malloc(sizeof(char)*actualCountOfFolders); 
    tokens = getTokens(path); 
    int i = 0; 
    for(i =0;i<actualCountOfFolders;i++){ 
    printf("Folders %s \n",tokens[i]); 
    } 
+0

関数が終了するとクリーンアップされる自動変数へのポインタを返さないでください。 – Unimportant

+1

このトークンを参照してくださいhttp://stackoverflow.com/questions/11656532/returning-an-array-using-c –

+0

あなたは 'トークン'のスペースを 'malloc'していますが、' tokens = getTokens(path); '割り当てられたメモリへのアクセスが失われます。 – Missu

答えて

1

問題は、ローカル変数へのポインタを返すことです。関数getTokensが返ってくると、すべての変数が有効範​​囲外になり、もはや存在しなくなります。配列tokensも同様です。あなたが上書きので、あなたが呼び出し前にメモリを割り当てる

は、ポインタがメモリリークにつながる、getTokensによって返されたポインタでmallocで返される(再割り当て)、重要ではありません。ああ、mallocは、actualCountOfFoldersバイト(文字)だけを割り当て、actualCountOfFoldersの数字はのポインタではなく、の文字に割り当てられるため、正しい量を割り当てていません。

2つの典型的な解決策は、getTokens関数内で動的に割り当てるか、配列を関数の引数として渡すことです。

0

関数内で作成されたローカル変数のアドレスを、その関数の出力として返さないでください。

クリーンアップが行われるため、一部の人々は言うでしょう。実際には、関数内でバッファを作成すると、このバッファの開始アドレスがその関数の下のスタック内で宣言されるので、関数とその戻り値を使ってバッファ全体が関数スタック内に格納されますデータはまだスタックアドレスに存在しますが、アドレスの範囲は関数スタックから下がっていません。関数呼び出しから実行されるので、別の関数が呼び出された場合、プログラムは新しい呼び出しまたは結果として新しい宣言された変数は、バッファの値が上書きされ、この書き込みを防ぐものはありません。これは、関数内で宣言されたローカルバッファまたは変数に対して起こります。

第二のコードが間違っている、malloc関数を使用して、実際には、あなたは、ヒープにメモリを割り当て、あなたがラインtokens = getTokens(path); を呼び出したら、関数によって返されたアドレスと、ヒープアドレスを上書きし、我々ので、これはメモリリークが発生します関数の範囲外になったときに関数スタックに格納されたデータを失うという問題に言及することなく、ヒープ内の割り当てられたメモリへのポインタを緩和します。

+0

はい、ローカル変数のアドレスではなく、ローカル変数のアドレス(このローカル変数へのポインタ)を意味します。ありがとうございました –