2012-01-07 17 views
0

私はプログラムの異なる場所の束に構造体の配列を割り当てる必要があります。したがって、関数を関数内に配置します(VS 2010)。コンパイラは使用されている初期化されていない変数について警告を出します。それでは、どのようにして関数に宣言するのですか?私は "&"と "*"の多くのバリエーションを試しましたが、無駄です。関数内のメモリ割り当てのためのポインタを渡す?

(私のコードは、吐き気の任意のフォームを起こした場合、私は事前に謝罪...私は英語の主要なんだ。)

struct s_stream { 
int blah; 
}; 

void xxyz(void) 
{ 
    struct s_stream **StreamBuild; 
    char *memBlock_1; 

    xalloc(StreamBuild, memBlock_1, 20); 
} 



void xalloc(struct s_stream **StreamStruct, char *memBlock, int structCount) 
{ 
    int i = sizeof(struct s_stream *); 
    if ((StreamStruct=(struct s_stream **) malloc(structCount * i)) == NULL) 
     fatal("failed struct pointer alloc"); 

    int blockSize = structCount * sizeof(struct s_stream); 
    if ((memBlock = (char *) malloc(blockSize)) == NULL) 
     fatal("failed struct memBlock alloc"); 

    // initialize all structure elements to 0 (including booleans) 
    memset(memBlock, 0, blockSize); 

    for (int i = 0; i < structCount; ++i) 
     StreamStruct[i]=(struct s_stream *) &memBlock[i*sizeof(struct s_stream) ]; 
} 
+0

正確に何をしようとしていますか? 'struct s_stream'オブジェクトの配列を動的に割り当てることですか? –

+0

コンパイラからの正確な警告を教えてください。特に、コンパイラはどのコード行を嫌うのですか? –

答えて

0

あなたはxallocへのポインタmemBlock_1コピーを渡しているので、mallocによって返されたアドレスをコピーに書き込まれ、決して呼び出し元の関数に到達していません。あなたは、おそらくアドレスがmemBlock_1xxyzが利用できるようにしたいので、あなたは、2番目の引数としてポインタへのポインタツー文字を渡す

void xalloc(..., char **memBlock, ...) 

xalloc(..., &memBlock_1, ...);でそれを呼び出す必要があります。 xallocの本文では、memBlockのすべての出現を*memblockと置き換えてください。 (*memblock = malloc(blockSize)) == NULL(キャストする必要はありません)。

同様に、xallocStreamStructパラメータはxxyzStreamBuildへのポインタへのポインタ構造体s_streamを変更することはありません。あなたの意図を正しく解釈する場合は、そのパラメータにポインタレイヤーを追加する必要があります(void xalloc(struct s_stream ***StreamStruct, ..., ...))。StreamBuildのアドレスを呼び出しに入れてxalloc(&StreamBuild, ..., ...)とし、関数本体のポインタを参照解除します。 (*StreamStruct = malloc(structCount * i)) == NULL

+0

私はあなたの助言に従った。残りの2つの問題:コンパイラは許可しません:(* StreamStruct = malloc(structCount * i))...(struct s_stream **)にキャストする必要があります。もう1つの問題は最後の2行で、ループしてポインタをメモリブロックに代入します。for(int i = 0; i PaeneInsula

+0

'malloc'の結果をキャストする必要がある場合は、CでなくC++としてプログラムをコンパイルしていることを意味します。おそらく大したことではないでしょうが、2人は、単純なプログラムが(mallocを返すようにキャストした後に)両方としてコンパイルして動作するという点で共通しています。ループでは、for(...)(* StreamStruct)[i] =&memBlock [...]; ' - 私は何かを見落とさない限り。うーん、「未処理例外」。うん、C++。 C++としてコンパイルしている場合(Microsoftのコンパイラでは悪い考えではなく、C99をサポートしていませんが、C++コンパイラとしてはうまくいきます)、 'new'などを使ってC++を書くことを検討するかもしれません。 –

+0

これは正しいですか? for(...)(* StreamStruct)[i] =&memBlock [...]; OR for(...)(* StreamStruct)[i] =(* memBlock)[...]; ?後者はうまくいくと思われますが、あなたが以前に言ったことと一貫しています... – PaeneInsula

3

私は私はあなたの質問を理解し、正確にわからないんだけど、それはのように思えますstruct s_streamオブジェクトの動的に割り当てられた配列を作成し、それらを呼び出し側に返す関数が必要です。そのような場合、それは非常に簡単です:

void easiest(void) 
{ 
    struct s_stream *array = malloc(20 * sizeof(struct s_stream)); 
} 

あなたは、独自の機能にオフmalloc()を移動し、ポインタを返すことができます:

void caller(void) 
{ 
    struct s_stream *array = create_array(20); 
} 

struct s_stream *create_array(int count) 
{ 
    return malloc(count * sizeof(struct s_stream)); 
} 

それとも、パラメータとして配列を渡すことを主張する場合:

void caller(void) 
{ 
    struct s_stream *array; 
    create_array(&array, 20); 
} 

void create_array(struct s_stream **array, int count) 
{ 
    *array = malloc(count * sizeof(struct s_stream)); 
} 
+0

あなたの最初の 'create_array()'は 'void *'を返すべきですか?あるいは 'struct stream * 'をタイプセーフな方が良いでしょう。 – alk

+0

Yup-typo。私はコンピュータに戻ったときに修正します。 –

+0

ちょっとしたプレッシャーの下で答えを書いていたときのコピー/ペーストエラーが修正されました。それについて申し訳ありません! –

0

通常の配列を使用していない理由はありますか?例えば;

struct s_stream* streamArray = malloc(sizeof(s_stream*structCount)); 

次に、あなたが余分なポインタを参照解除することなく、streamArray [structCount-1]に[0] streamArrayとだけアクセスできるs_streamの配列を持っています。

+0

それは私が元々やっていた方法です。しかし、私は配列(これは240万のメンバーです)でqsortを使用しようとしています。重い再帰がスタックオーバーフローを引き起こしました。だから代わりにポインタを使用してソートしようとしています.... – PaeneInsula

関連する問題