2017-05-29 96 views
0

我創建了一小段代碼來動態分配C數組中的二維數組,這用於嘗試解決我在較大的一段代碼上遇到的問題,如果可以的話讓我的腦袋動態分配一個二維陣列我相信我會解決我的其他問題。我遇到的問題是,在分配了矩陣並使用函數寫入它之後,我的程序無法運行,我沒有收到任何錯誤,它只是創建一個空白屏幕並最終崩潰。我不知道從哪裏進步,任何幫助將不勝感激!動態分配的二維數組出錯

下面是代碼:

#include <stdlib.h> 

void get_matrix(double **a, int n); 

int main() { 
    int n = 5; 
    int i, j; 
    double **a; 

    a = (double **)malloc(n * sizeof(double *)); 
    for (j = 0; j < n; j++) 
     a[j] = (double *)malloc(n * sizeof(double)); 

    get_matrix(a, n); 

    for (i = 0; i <= n; i++) { 
     for (j = 0; j <= n; j++) { 
      printf("%d, ", a[i][j]); 
     } 
     printf("\n, "); 
    } 
    return 0; 
} 

void get_matrix(double **a, int n) { 
    int i, j; 

    for (i = 0; i <= n; i++) { 
     for (j = 0; j <= n; j++) { 
      a[i][j] = 4; 
     } 
    } 
} 
+0

你看過[this](https://stackoverflow.com/q/42094465/694733)嗎? – user694733

+0

@DavidBowling:嚴格來說,你是對的。爲什麼不用c99代碼發佈一個答案,它可以分配和使用2D VLA?語法比上面發佈的2D間接數組代碼複雜一些。 – chqrlie

+0

@DavidBowling:還有一些其他問題,我發佈了一個更完整的答案。 – chqrlie

回答

2

有你的代碼中的多個問題:

  • 你不包括<stdio.h>
  • 你的循環指標ij運行過火:因爲索引是基於在C,你爲零必須在n之前停止,否則您將嘗試訪問陣列外部的元素。這個錯誤會導致未定義的行爲,這是你觀察到的一個合理的解釋。
  • 您通過double%dprintf轉換規範。改爲使用%g
  • 您可以在行首打印額外的逗號。
  • 你的數組並不是真正的二維數組,它是一個間接數組。在C99中,您可以分配和使用具有參數大小的動態數組,稱爲VLA。看看下面的語法:

這裏是一個改進版本:

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

static void get_matrix(int n, double a[n][n]) { 
    for (int i = 0; i < n; i++) { 
     for (int j = 0; j < n; j++) { 
      a[i][j] = 4; 
     } 
    } 
} 

int main(void) { 
    int n = 5; 
    double (*a)[n] = malloc(sizeof(*a) * n); 

    get_matrix(n, a); 

    for (int i = 0; i < n; i++) { 
     for (int j = 0; j < n; j++) { 
      printf("%g, ", a[i][j]); 
     } 
     printf("\n"); 
    } 
    return 0; 
} 
+0

你打敗了我!爲了挑剔,我喜歡使用'malloc(sizeof * a * n)',習慣上首先放置'sizeof'表達式。當你有多個乘法時,這減少了溢出的機會:'malloc(sizeof * a * x * y)'。我會''size_t'用於'n'和數組索引。 –

+1

@DavidBowling:好點,我通常也是出於完全相同的原因,但爲了清晰起見,我更喜歡'sizeof(* a)* n'。我被'malloc(x * y * sizeof(* p))'''用'x'和'y'小於'size_t'整數捕獲了一次,溢出並不容易發現,即使盯着代碼。通過一次乘法,這不是問題,但一致性是一個金科玉律。 – chqrlie

+0

你好!自從你上次幫助我上個星期以來,我一直無法解決這個問題!我對它的寫法做了一些修改,運行良好,唯一的問題是當我打印矩陣時它只打印零點? –

2

問題是for循環。您的for循環現在運行n + 1次,而不是n次。這意味着您正試圖在未分配的內存區域上寫入某處。

for (i=0; i<=n; i++)

應該是:

for (i=0; i<n; i++)

你必須使用條件是少代替小於或等於


雖然我可以看到你的代碼,我也建議一些技巧,通過的sizeof直接使用變量,以避免以後的問題:

a = (double **) malloc (n * sizeof(*a)); 

這將自動檢測*asizeof這是需要分配尺寸。

+0

這就是它排序謝謝你!你已經解決了頭痛! :) –

+0

很高興聽到;)如果它適合你,你可以點擊「正確答案」來確認它。 – tilz0R

1

您的索引是基於零的。這意味着您使用<而不是< =來檢查for循環的結束條件。 0..n-1是您分配的n個位置。

#include <stdlib.h> 

void get_matrix (double **a, int n); 

int main() 

{ 
    int n = 5; 
    int i, j; 
    double **a; 



    a = (double **) malloc (n * sizeof(double *)); 
    for (j = 0; j < n; j++) 
     a[j] = (double *) malloc (n * sizeof(double)); 

    get_matrix (a, n); 

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

    return 0; 

} 

void get_matrix (double **a, int n) 
{ 
    int i, j; 

    for (i=0; i<n; i++) 
    { 
     for (j=0; j<n; j++) 
     { 
      a[i][j] = 4; 
     } 
    } 
} 
+0

非常感謝! –

+0

此代碼具有未定義的行爲,因爲'a [i] [j]'是一個'double',正在打印一個'%d'轉換說明符。 –

0

我一直沒能在這個問題上的工作,因爲你上次上週幫我出去!我對它的寫法做了一些修改,運行良好,唯一的問題是當我打印矩陣時它只打印零點?

我已在下面包含修訂後的代碼。

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

void get_matrix (double **a, int n); 
void print_matrix (double **a, int n); 

int main() 

{ 
    int n = 5; 
    int i, j; 
    double **a; 



    a = (double **) malloc (n * sizeof(double *)); 
    for (j = 0; j < n; j++) 
     a[j] = (double *) malloc (n * sizeof(*a)); 

    get_matrix (a, n); 
    print_matrix (a, n); 


    return 0; 

} 

void get_matrix (double **a, int n) 
{ 
    int i, j; 

    for (i=0; i<n; i++) 
    { 
     for (j=0; j<n; j++) 
     { 
      a[i][j] = 4; 
     } 
    } 
} 

void print_matrix (double **a, int n) 
{ 
    int i, j; 

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