簡體   English   中英

如何在C函數中將2D數組用作輸出參數

[英]How to use a 2D array as an output parameter in a function in C

我正在編寫一個程序,使用Floyd算法計算圖形上兩點之間的最短路徑。 我需要先寫入一個二進制文件,然后從中讀取並打印圖形。 我的問題就在這里,因為我的函數簽名必須采用以下形式: void read_graph(char *filename, int *n, int ***A)

我寫了以下內容:

void read_graph(char *filename, int *n, int ***A)
{
    FILE *fin;
    size_t i;
    int x;
    int **arr;

    fin  = fopen(filename, "rb");
    if (fin == 0) {
        printf("Error opening file\n");
        exit(1);
    } else {
        fread(&x, sizeof(int), 1, fin);
        printf("Read size of matrix %d\n",x);
        *n = x;
        fseek(fin, sizeof(int)+1, SEEK_SET);
        arr = malloc(x*sizeof(int *));
        if (arr == NULL) {
            printf("Not enough space.\n");
        }
        for (i = 0; i < x; ++i) {
            arr = malloc(x*sizeof(int));
        }
        for (i = 0;  i < x; ++i) {
            fread(arr,sizeof(int), x, fin);
        }

        //  ***A = **arr;    
    }
    fclose(fin);
    free2darray(*A, x);
}

free2darray是一個實用程序函數,用於釋放內存。 我的問題是,如果在調用此函數之前分配了一個2d數組,則此函數有效。 但是,要求此函數將2d數組返回***A而不是相反。 如果您能告訴我我在做什么錯,那將非常有幫助。 也歡迎批評代碼風格。

編輯:這是我現在如何調用函數:

int **arr;
   int x;
   size_t i;
   arr = malloc(5*sizeof(int*));
   if (arr == NULL) {
     printf("Cannot allocated memory for array\n");
     exit(1);
   }
   for (i = 0; i < 5; i++) {
     arr[i] = malloc(5*sizeof(int));
   }
   read_graph("test.dat", &x, &arr); 

5只是測試大小。 以前通過使用隨機值填充5 * 5數組來編寫test.dat

謝謝

你近了 如果幾分鍾前讀完我的答案,您可能已經注意到我的解決方案返回了指向動態數組的指針。 然后我在對您的問題的評論中看到函數原型是給定的,因此我修改了答案。

main()您需要做的就是聲明一個指向int的指針以存儲矩陣的大小,以及一個指向int的指針的指針,該指針將傳遞給函數read_graph() 盡管不是嚴格必需的,但出於良好的風格,我繼續將指針( arr )初始化為NULL。 我在此處添加了幾行內容來顯示新數組的內容。

您需要在退出之前釋放分配的內存。 這是原始代碼中的主要問題之一:在對read_graph()的調用結束時釋放了內存。 您需要等到不再需要數組內容后再釋放這些分配。

我發現的另一個問題是,當你的動態數組的各行分配的內存,你忘了指數arr ,所以你malloc版內存分配的地址相同的指針x倍。 這是您的循環,反復將內存重新分配給arr (並且是內存泄漏,因為丟失了對先前分配的引用):

for (i = 0; i < x; ++i) {
    arr = malloc(x*sizeof(int));
}

傳遞給函數的指針A用於接收對malloc()的調用結果,以便從調用函數中看到分配的內存。 因為您最初為此目的在read_graph()內部聲明了一個指針,所以這會稍微改變您的某些分配。 我還更改了將值讀入數組的循環,以使其一次讀取一個值-好像您試圖一次讀取x

您真的不需要fseek()因為文件指針已經就位,所以我刪除了這一行。 我還添加了檢查以確保數據文件正確關閉。 我制作了一個測試數據文件,一切似乎正常。 我也將您的size_t變量更改為int 我這樣做是因為在生成編譯器警告的循環中有int值與size_t值的比較。 該代碼仍然可以正常運行,但是忽略警告毫無意義。 我會將所有內容更改為size_t ,但是您從文件中讀取了矩陣的大小,而這是代碼中的int 如果您可以稍微更改文件格式,則矩陣的大小可以存儲為size_t值。 這是修改后的代碼:

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

void read_graph(char *filename, int *n, int ***A);
void free2darray(int ***A, int n);

int main(void)
{
    int x;
    int **arr = NULL;
    int i, j;

    read_graph("test.dat", &x, &arr); 

    for (i = 0; i < x; i++) {
        for (j = 0; j < x; j++)
            printf("%d ", arr[i][j]);
        putchar('\n');
    }

    /* Free allocated memory */
    free2darray(&arr, x); 

    return 0;
}

void read_graph(char *filename, int *n, int ***A)
{
    FILE *fin;
    int i;
    int x;

    fin  = fopen(filename, "rb");
    if (fin == 0) {
        printf("Error opening file\n");
        exit(1);
    } else {
        fread(&x, sizeof(int), 1, fin);
        printf("Read size of matrix %d\n",x);
        *n = x;

        *A = malloc(x*sizeof(int *));
        if (*A == NULL) {
            printf("Not enough space.\n");
        }
        for (i = 0; i < x; ++i) {
            (*A)[i] = malloc(x*sizeof(int));
        }
        for (i = 0; i < x; ++i)
            for (int j = 0; j < x; ++j)
                fread(&(*A)[i][j], sizeof(int), 1, fin);
    }

    if (fclose(fin) != 0)
        fprintf(stderr, "Unable to close file\n");
}

void free2darray(int ***A, int n)
{
    for (int i = 0; i < n; i++)
        free((*A)[i]);
    free(*A);
}

編輯

我必須創建一個測試文件,因此為此添加了一些上面未顯示的代碼。 它讀取一個文本文件並創建該程序可以使用的二進制文件。 生成的二進制文件只是一個int序列。 我只是將代碼放在main()的開頭,並在與“ a.out”相同的目錄中創建了一個名為“ testdat.txt”的文件。 我的文本文件的第一行包含5,然后是25個整數,每行包含一個:

5
1
2
3
4
5
....

這是代碼:

/* Code to create a datafile from a text file */

FILE *fpin, *fpout;
char nstr[100];
int num_out;

fpin = fopen("testdat.txt", "r");
fpout = fopen("test.dat", "wb");
while (fgets(nstr, 100, fpin) != NULL) {
    num_out = atoi(nstr);
    fwrite(&num_out, sizeof(int), 1, fpout);
}
fclose(fpin);
fclose(fpout);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM