2011-09-28 5 views
0

this answer後、私は私が正しく理解し確認するために簡単な例を作った:Cでは、関数内からポインタへのポインタを初期化する方法は?

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

typedef struct 
{ 
    int x; 
} data; 

void fill_data (data *** ptr_all, int l) 
{ 
    int i = 0; 
    *ptr_all = (data**) calloc(l, sizeof(data)); 
    if ((*ptr_all) == NULL){ 
    fprintf(stderr, "error: can't allocate memory"); 
    abort(); 
    } 
    for (i = 0; i < l; i++) 
    { 
    data * d = (data*) calloc(1, sizeof(data)); 
    if (d == NULL){ 
     fprintf(stderr, "error: can't allocate memory for %i-th data", i+1); 
     abort(); 
    } 
    d->x = i; 
    (*ptr_all)[i] = d; 
    } 
} 

int main(int argc, char *argv[]) 
{ 
    int i = 0, l = 5; 
    data ** all = NULL; 

    fill_data (&all, l); 

    for (i = 0; i < l; i++) 
    { 
    printf("%i\n", all[i]->x); 
    } 

    return EXIT_SUCCESS; 
} 

はしかし、それをコンパイルし、実行した後、私は最初の要素が間違っていることを参照してください。

$ gcc -Wall test.c 
$ ~/bin/a.out 
161276080 
1 
2 
3 
4 

私がすることができますが私の関数でそれを参照してくださいfill_data私はptr_allを初期化しませんが、* ptr_allだけを初期化します。これが問題の原因かもしれません。しかし、どうすればいいですか?

+0

うまく動作すると思われます。http://www.ideone.com/ZPU2W – Praetorian

+0

値がすでに&allであるため、ptr_allをfill_dataに割り当てる必要はありません。私はあなたの最初のcallocは 'sizeof(data *)'を持っているべきだと思います –

+0

私はこの質問に答えるつもりはありませんが、1つのアドバイス:ポインタへのポインタからポインターへのポインタが必要だと思ったら、おそらくデザインが間違っています。ポインターへのポインターは、ほぼすべての目的に十分なはずです。 –

答えて

5

変更:

*ptr_all = (data**) calloc(l, sizeof(data)); 

へ:

*ptr_all = (data**) calloc(l, sizeof(data*)); 

あなたがlポインタを割り当てする必要があるのに対し、あなたはl int型を割り当てています。 64ビットOS(これはsizeof(void *) > sizeof(int))でこれを構築して実行することはほぼ確実です。さもなければ、このバグは休止したままになります。

関連する問題