如何使用动态内存分配对矩阵执行不同的操作?

时间:2015-08-11 18:33:32

标签: c arrays matrix

此程序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));
    }

还有seg。错误,这次它没有为任何订单的矩阵产生正确的输出。

以下是我的完整代码:

#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

在乘法函数中也存在一些问题,也没有显示右矩阵。

2 个答案:

答案 0 :(得分:0)

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

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

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

这会覆盖此数组的第一个c元素。如果是c>r,那么

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

上述行的行为未定义。如果c<=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 */

答案 1 :(得分:0)

使用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)矩阵。