2017-05-29 99 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 "); 
    } 
}