2011-09-17 4 views
0

私はこのコードをしました:出力パラメータはローカル参照を返す原則に違反していると考えられますか?

#include <stdio.h> 
#include <stdlib.h> 
#define OUT 

void getDataFromServer(OUT int** array, OUT int* size) 
{ 
    int tmpArr[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 
         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; 
    *size = sizeof tmpArr/sizeof(int); 
    *array = tmpArr; 
} 

int main(void) 
{ 
    int size = 0; 
    int* dataFromServer; 
    getDataFromServer(&dataFromServer, &size); 

    int x; 
    for (x=0; x < size; x++) 
     printf("%d ", dataFromServer[x]); 
    printf("\n\n"); 

    return 0; 
} 

これが原因関数にローカルOUT int** arrayパラメータアクセスデータの..ですメインプリントガベージデータ内のループのために?

ありがとうございました。

答えて

1

getDataFromServerが終了すると、すべてのローカル変数がスタックからポップされます。あなたが使用しているポインタは、多少拭き取られたメモリ領域を指しています。 mallocを使用して、(ヒープ上の)新しく割り当てられたメモリにデータをコピーするか、tmpArrstatic変数にします。

2

はい、正確です。 tmpArrgetDataFromServerにローカルなので、関数が返っても存在しなくなります。それへのポインタがガーベジへのポインタになりました。

サーバーからのデータを保持するためのメモリの割り当てを担当する担当者と、そのサーバーを解放する担当者を考える必要があります。この場合、関数はそれを解放する責任がありますが、明らかに機能しません。どちらの側も割り当てることができますが、発信者は自由にしなければなりません!

3

はい、どのようにしても、関数からローカル変数のアドレスを送信することはできず、関数が返ってもそれが有効であることを期待することはできません。同じ引数が関数の戻り値または "outパラメータ"に対して保持されます。または、通常、ローカル変数を指すようにメモリ位置を設定します。

変数がスタックから削除されたり、「ゴミ」になることがよくあります。実際に何が起こるかは、他の関数のローカル変数、他の関数を呼び出すためのパラメータなどのためにスペースが再利用されていることを認識するのに役立ちます。これは、 "ゴミ"変数が有効であるように見えることがあるスペースはまだ再利用されていません。

+2

また、**再使用されていないスペースに頼ることはできません**注意が必要です。コンパイラは、必要なものに対しては一時的なスタック領域を使用できますが、これはコンパイラのバージョンによって変更される可能性があります。また、コードが実行されている間に呼び出される非同期シグナルハンドラでスタックを使用することができ、競合状態のバグを追跡することが困難になります。原則として、あなたのプロセスが実行される予定でないときに、プロセス状態の簿記を使用するためにカーネルがスタックを使用することもできると思います。 –

+0

@R:絶対に! –

関連する問題