【问题标题】:How to perform different operations on matrix using dynamic memory allocation?如何使用动态内存分配对矩阵执行不同的操作?
【发布时间】:2015-11-04 03:09:02
【问题描述】:

此程序的case 5 存在分段错误(转置)仅当输入行大于输入列的行时才会发生此分段错误。希望这是因为我没有相应地分配内存。

b= (int**)malloc(r*sizeof(int*));
    for(i=0; i<c; i++)
    {
        b[i] = (int*)malloc(sizeof(int));
    }

如果我这样做是这样的:

b= (int**)malloc(c*sizeof(int*));
    for(i=0; i<r; i++)
    {
        b[i] = (int*)malloc(sizeof(int));
    }

还有段。错误,这一次它没有为任何顺序的矩阵产生正确的输出。

这是我的完整代码:

#include<stdio.h>
#include<stdlib.h>
int** inputmatrix(int **a,int r, int c)
{
    int i, j;
    a = (int**)malloc(r*sizeof(int));
    for(i=0; i<c; i++)
    {
        a[i] = (int*)malloc(sizeof(int));
    }
    printf("\n Input the Elements of the Matrix :");
    for(i=0; i<r; i++)
    {
        for(j=0; j<c; j++)
        {
            scanf("%d",&a[i][j]);
        }
    }
    return a;
}
void showmatrix(int** a, int r, int c)
{
    int i, j;
    for(i=0; i<r; i++)
    {
        printf("\n");
        for(j=0; j<c; j++)
        {
            printf("  %d",a[i][j]);
        }
    }
}

int** add(int **a, int **b, int r, int c)
{
    int i,j;

    for(i=0; i<r; i++)
    {
        for(j=0; j<c; j++)
        {
            a[i][j] = a[i][j]+b[i][j];
        }
    }
    return a;
}
int** multiplication(int** a, int **b, int r1, int c1, int c2)
{
    int **c,i,j,k;
    c = (int**)malloc(r1*sizeof(int*));
    for(i=0; i<c2; i++)
    {
        c[i] = (int*)malloc(sizeof(int));
    }
    for(i=0; i<r1; i++)
    {
        for(j=0; j<c2; j++)
        {
            c[i][j] = 0;
            for(k=0; k<c1; k++)
            {
                c[i][j] = c[i][j] + a[i][k]*b[k][j];
            }
        }
    }
    return c;
}

int minval(int **a, int r, int c)
{
    int i, min;
    min = a[r][0];
    for(i=0; i<c; ++i)
    {
        if(a[r][i]<min)
        {
            min = a[r][i];
        }
    }
    return min;
}

int maxval(int **a, int r, int c)
{
    int i, max;
    max = a[0][c];
    for(i=0; i<r; ++i)
    {
        if(a[i][c] > max )
        {
            max = a[i][c];
        }
    }
    return max;
}

void saddlepoint(int **a, int r, int c)
{
    int i, j, rpos, cpos, flag = 0,sp;
    for(i=0; i<r; ++i)
    {
        for(j=0; j<c; ++j)
        {
            if(a[i][j] == minval(a, i, c) && a[i][j] == maxval(a, r, j))
            {
                sp = a[i][j];
                flag = 1;
                rpos = i;
                cpos = j;
            }
        }
    }
    if(flag == 1)
    {
        printf("\n The Saddle point of the Matrix is found at position (%d,%d) value is %d ", rpos, cpos,sp);
    }
    else
    {
        printf("\n There is no saddle point in the Matrix ");
    }
}

int magicsquare(int **a, int r, int c)
{
    int i, j, row_sum, col_sum, d1, d2, flag = 0;
    if(r==c)
    {
        for(i =0 ;i<r; i++)         // for digonals
         {
            d1 = d1 + a[i][i];
            d2 = d2 + a[i][r-i-1];
        }
        for(i=0; i<r; i++)
        {
            row_sum = 0;
            for(j=0; j<c; j++)
            {
                row_sum = row_sum + a[i][j];
            }
            if(row_sum == d1)
                flag = 1;
            else
                break;
        }
        for(i=0; i<r; i++)
        {
            col_sum = 0;
            for(j=0; j<c; j++)
            {
                col_sum = col_sum + a[j][i];
            }
            if(col_sum == d1)
                flag =1;
            else
                break;
        }
    }
    else
    {
        printf("\n This Matrix is not a Magic Square ");
    }
    return flag;
}

int** transpose(int **a, int r, int c)
{
    int i, j, **b;
    b= (int**)malloc(c*sizeof(int*));
    for(i=0; i<r; i++)
    {
        b[i] = (int*)malloc(sizeof(int));
    }
    for(i =0; i<r; i++)
    {
        for(j=0; j<c; j++)
        {
            b[j][i] = a[i][j];
        }
    }
    return b;
}

int main()
{
    int **a, **b,r1,c1,r2,c2, i,j,ch,f;
    int **c;
    printf("\n enter your choice : \n1.Addition \n2.Multiplication \n3.Saddle Point \n4. Magic Square \n5.Transpose\n");
    scanf("%d",&ch);
    printf("\n enter the oder of matrix A :");
    scanf("%d%d",&r1,&c1);
    a = inputmatrix(a,r1,c1);
    switch(ch)
    {
        case 1:
                printf("\n enter the oder of matrix B :");
                scanf("%d%d",&r2,&c2);
                if(r1==r2 && c1==c2)
                {
                    b = inputmatrix(b,r2,c2);
                    a = add(a,b,r1,c1);
                    printf("\n the result of the addition of matrices is :");
                    for(i=0; i<r1; i++)
                    {
                        printf("\n");
                        for(j=0;j<c1; j++)
                        {
                            printf("%d\t",a[i][j]);
                        }
                    }
                }
                else
                {
                    printf("\n these matrices can't be added ");
                }
                break;
        case 2 :
                printf("\n Enter the Order of Matrix B :");
                scanf("%d%d",&r2,&c2);
                b = inputmatrix(b,r2,c2);
                if(c1 == r2)
                {
                    c = multiplication(a, b, r1, c1, r2);
                    for(i=0; i<r1; i++)
                    {
                        printf("\n");
                        for(j=0; j<c2; j++)
                        {
                            printf("%d\t",c[i][j]);
                        }
                    }
                }
                else
                {
                    printf("\n Sorry, These Matrices Can't be Multiplied ");
                }
                break;
        case 3 :
                printf("\n The Matrix you Entered is :");
                for(i=0; i<r1; i++)
                {
                    printf("\n");
                    for(j=0; j<c1; j++)
                    {
                        printf("  %d",a[i][j]);
                    }
                }
                saddlepoint(a,r1,c1);
                break;
        case 4 :
                printf("\n The Matrix you Entered is :");
                for(i=0; i<r1; i++)
                {
                    printf("\n");
                    for(j=0; j<c1; j++)
                    {
                        printf("  %d",a[i][j]);
                    }
                }
                int f =  magicsquare(a, r1, c1);
                if(f==1)
                    printf("\n This Matrix is a Magic Square ");
                else
                    printf("\n This Matrix is not a Magic Square ");
                break;
        case 5 :
                printf("\n The Matrix you enter is :");
                showmatrix(a,r1,c1);
                b = transpose(a,r1,c1);
                printf("\n the transpose of the entered matrix is :");
                for(i=0; i<c1; i++)
                {
                    printf("\n");
                    for(j=0; j<r1; j++)
                    {
                        printf("  %d",b[i][j]);
                    }
                }
                break;

        default : printf("\n Sorry, This is a Wrong Choice ");
            }
    return 0;
}

下面还有一些输出案例:

案例 1:

enter your choice : 
1.Addition 
2.Multiplication 
3.Saddle Point 
4. Magic Square 
5.Transpose
5

enter the oder of matrix A :3
2

Input the Elements of the Matrix :1
2
3
4
5
Segmentation fault (core dumped)

案例 2:

enter your choice:
1.Addition 
2.Multiplication 
3.Saddle Point
4. Magic Square 
5.Transpose
5

enter the oder of matrix A :2
3

Input the Elements of the Matrix :1
2
3
4
5
6

The Matrix you enter is :
1  2  3
4  5  6
the transpose of the entered matrix is :
1  4
2  5
3  6

而且乘法函数也有问题,右矩阵也没有显示出来。

【问题讨论】:

  • TL:DR : 您是否尝试在分配和循环这两种情况下使用rc
  • b= (int**)malloc(r*sizeof(int*)); for(i=0; i&lt;r; i++) { b[i] = (int*)malloc(c*sizeof(int)); }
  • 当您在调试器下运行时,哪一行引发了段错误?
  • @BLUEPIXY 仍然分段。执行你告诉我的事情后出现错误,我不这样做有任何理由做你告诉我的事情
  • b[i] = (int*)malloc(sizeof(int)); 只为列分配一个元素。

标签: c arrays matrix


【解决方案1】:

使用 malloc 声明数组有错误。 当您希望声明一个 'r' 行和 'c' 列的二维数组时,语句应该类似于

int **arr=malloc(r*sizeof(int *));

for(i=0;i<r;i++)
    arr[i]=malloc(c*sizeof(int));

这将消除分段错误。

第一条语句声明了一个 'r' 整数指针数组。

for 循环执行 'r' 次,因为您必须初始化前一条语句声明的每个 'r' 指针。

for 循环内的语句声明了一个长度为“c”的整数数组来存储每行的“c”个元素。 此外,它用这些行的地址初始化数组 'arr' 的每个指针(当然顺序正确)。

因此,我们得到 'r' 行,每行有 'c' 个元素,因此得到一个 (r x c) 矩阵。

【讨论】:

    【解决方案2】:
    b= (int**)malloc(r*sizeof(int*));
    

    这会分配一个由r int* 元素组成的数组。

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

    这会遍历此数组的第一个 c 元素。如果c&gt;r,那么

     b[i] = (int*)malloc(sizeof(int));
    

    上面一行的行为是未定义的。如果c&lt;=r,它定义明确但不是很有用,因为它为每个矩阵行分配一个元素。当您尝试访问超过第一列的元素时,它可能会在以后损坏。

    要分配具有r 行和c 列的矩阵,您可能需要这样做:

    b = malloc(r * sizeof(int*));              /* allocate `r` rows */
    for(i = 0; i < r; i++)                     /* for each of the `r` rows */
       b[i] = malloc (c * sizeof(int));        /* allocate `c` columns */
    

    【讨论】:

      猜你喜欢
      • 2021-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-18
      相关资源
      最近更新 更多