2

あなたに質問があります!

メイン関数に動的な 2 次元配列がある C プログラムがあります。

int **neighbours;

コマンドラインからの引数に基づいて初期化します。問題は、コードを少しクリーンアップしたいということです。これを行うには、初期化されていない配列を参照引数として受け取り、そこで初期化する関数をヘッダー ファイルに作成します。

これは私が関数を呼び出す方法です:

init(&nodeNum, &neighbours, argv[1], &nodes);

これは、ヘッダー ファイルで関数を宣言する方法です。

int init(int *nodeNum, int ***neighbours, char *arg, struct node **nodes)

そして、これはメモリを割り当てる方法です:

neighbours=malloc(*nodeNum*sizeof(int *));
        for(i=0;i<*nodeNum;i++){
            neighbours[i] = malloc(*nodeNum*sizeof(int *));
        }

明らかに何かがうまくいかず、クラッシュします! 私が間違っているかもしれないことについてのヒントはありますか?

何人かの親切な人々の助けのおかげで、malloc は機能するようになりましたが、ノードを埋めることはできません!

関数のコード全体は次のとおりです。

int init(int *nodeNum, int ***neighbours, char *arg, struct node **nodes){
FILE *file;
char buffer[4];
int i,y,distance;

if(strcmp(arg,"-l")==0){
        file = fopen("C:\\Users\\trendkiller\\thesis\\matrix.txt","r");
        printf("parsing adjacency matrix from file\n\n");
        //file = fopen ("C:\\Users\\trendkiller\\thesis\\matrix.txt", "r" ) ;
        *nodeNum = atoi(fgets(buffer,4,file));
        *neighbours=malloc(*nodeNum*sizeof(int *));
        for(i=0;i<*nodeNum;i++){
            (*neighbours)[i] = malloc(*nodeNum*sizeof(int *));
        }
        printf("this prints\n");
        printf("number of nodes: %s", buffer);
        for(i=0;i<*nodeNum;i++){
            for(y=0;y<*nodeNum;y++){
                fgets(buffer,4,file);
                (*neighbours)[i][y]=atoi(buffer);
                            }
        }


    }
    else{
        *nodeNum = atoi(arg);

        *neighbours=malloc(*nodeNum*sizeof(int *));
        printf("this prints\n");
        for(i=0;i<*nodeNum;i++){
            (*neighbours)[i] = malloc(*nodeNum*sizeof(int *));
        }

        *nodes=malloc(*nodeNum*sizeof(struct node));

        for(i=0;i<30;i++){
            (*nodes)[i].x=rand()%100;
            (*nodes)[i].y=rand()%100;
        }
        printf("this prints\n");

        printf("creating new adjacency matrix\n\n");
        for(i=0; i<*nodeNum; i++){
            for(y=0; y<*nodeNum; y++){
                distance=sqrt((((*nodes)[y].x-(*nodes)[i].x)*((*nodes)[y].x-(*nodes)[i].x))+(((*nodes)[y].y-(*nodes)[i].y)*((*nodes)[y].y-(*nodes)[i].y)));
                if(i==y){
                    (*neighbours)[i][y]=-1;
                }
                else if(distance<=20){
                    (*neighbours)[i][y]=1;
                }
                else {
                    (*neighbours)[i][y]=0;
                }
            }

        }

        file = fopen("C:\\Users\\trendkiller\\thesis\\matrix.txt","a+");
        fprintf(file,"%d\n",*nodeNum);
        for(i=0;i<*nodeNum;i++){
            for(y=0;y<*nodeNum;y++){
                fprintf(file,"%d\n", (*neighbours)[i][y]);
            }
        }
    }

0 を返します。

}

よろしくお願いします。

4

2 に答える 2

1

問題は、neighbours値によって渡されるため、関数内で変更しても効果がないことです。ポインターで渡し、間接的に変更する必要があります。

int init(int *nodeNum, int ***neighbours_ptr, char *arg, struct node *nodes) {
    *neighbours_ptr = malloc(*nodeNum*sizeof(int *));
    for(i=0;i<*nodeNum;i++){
        (*neighbours_ptr)[i] = malloc(*nodeNum*sizeof(int *));
    }
}

の 2 番目の引数としての&neighbours代わりに渡す必要もあります。neighboursinit

于 2012-06-25T22:02:35.743 に答える
0

サンプル コードでは、1 つのエラーを示します。

neighbours[i] = malloc(*nodeNum*sizeof(int *));

どこにあるべきか

neighbours[i] = malloc(*nodeNum*sizeof(int));

実際の配列ではなく、2D 配列のエミュレーションを使用するのはなぜですか? これはC99以降で機能します:

int (*neighbours)[nodeNum] = malloc(sizeof(int[nodeNum][nodeNum]));

initメモリを割り当てるだけの必要はありません。

nodeNum値を直接渡すのではなく、ポインターを渡すのはなぜですか? init割り当てだけでなく、初期化を行う関数がまだ必要な場合。インターフェイスは次のようになります

void init(size_t nodeNum, int neighbours[nodeNum][nodeNum]);
于 2012-06-25T22:42:10.893 に答える