简体   繁体   English

C中的分段错误(具有动态内存分配的2D阵列)

[英]Segmentation fault (2D array with dynamic memory allocation) in C

I am still getting a hang of using malloc, calloc or realloc. 我仍然无法使用malloc,calloc或realloc。 Pretty sure I'm getting a segmentation fault because of an incorrect pointer or something, but for the life of me, I don't understand where I'm doing it wrong. 可以肯定的是,由于指针不正确或其他原因而导致分段错误,但是对于我的生命,我不知道自己在哪里做错了。 The program works when the user input is '5 5', anything other than that causes the program to act weird and often times fail with a segmentation fault. 当用户输入为“ 5 5”时,该程序将运行,否则会导致该程序运行异常,并且经常会因分段错误而失败。 Matrix A and B should be filled with random numbers, and Matrix C should sum matrix A and B, all the while using dynamic memory allocation. 矩阵A和B应该使用随机数填充,并且矩阵C应该始终使用动态内存分配对矩阵A和B求和。 I'm not familiar with allocs, I've just started to understand pointers and 2D arrays. 我对分配不熟悉,我才刚刚开始了解指针和2D数组。 Can somebody explain what I'm doing wrong. 有人可以解释我在做什么错。 Here's the whole code. 这是完整的代码。

#include <stdio.h>
#include <stdlib.h>
#define ROWS 10
#define COLUMNS 10

void fillMatrix (int *matrix, int rows, int columns)
{
    int i, j;
    for(i = 0; i < rows; i++)
    {
        for(j= 0; j < columns; j++)
        {
            matrix[i * COLUMNS + j] = (rand() % 10) + 1;
        }
    }
}
void printMatrix (int *matrix, int rows, int columns)
{
    int i, j;
    for(i = 0; i < rows; i++)
    {
        for(j= 0; j < columns; j++)
        {
            printf("%2d ", *(matrix + i * COLUMNS + j));
        }
    printf("\n\n");
    }
}
void sumMatrix (int *matrix, int *matrixA, int *matrixB, int rows, int columns)
{
    int i, j;
    for(i = 0; i < rows; i++)
    {
        for(j= 0; j < columns; j++)
        {
            matrix[i * COLUMNS + j] = matrixA[i * COLUMNS + j] + matrixB[i * COLUMNS + j];
        }
    }
}

int main()
{
    int *matrixA = NULL, *matrixB = NULL, *matrixC = NULL;
    int matrix[ROWS][COLUMNS], r, s, i;
    srand((unsigned) time(NULL));
    do{
    printf("Rows and columns (min 1 1, max 10 10): ");
    scanf("%d %d", &r, &s);
    }while(r > ROWS || r < 1 || s > COLUMNS || s < 1);

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

    printf("\nMatrix A:\n\n");
    fillMatrix(matrixA, r, s);
    printMatrix(matrixA, r, s);

    matrixB = calloc(r, sizeof(int *));
    for (i = 0; i < r; i++)
        matrixB[i] = calloc(s, sizeof(int));

    printf("\nMatrix B:\n\n");
    fillMatrix(matrixB, r, s);
    printMatrix(matrixB, r, s);

    matrixC = calloc(r, sizeof(int *));
    for (i = 0; i < r; i++)
        matrixC[i] = calloc(s, sizeof(int));

    printf("\nSummed up (Matrix C):\n\n");
    sumMatrix(matrixC, matrixA, matrixB, r, s);
    printMatrix(matrixC, r, s);

    free(matrixA);
    free(matrixB);
    free(matrixC);
    return 0;
}

You access all your matrices as single-dimension arrays, and should therefore allocate them accordingly. 您将所有矩阵作为一维数组访问,因此应相应地分配它们。

For example: int* matrixA = malloc(r*s*sizeof(int)); 例如: int* matrixA = malloc(r*s*sizeof(int)); .

That's all; 就这样; no need to do the for (i = 0; i < r; i++) loops. 无需执行for (i = 0; i < r; i++)循环。

In addition, you are using the COLUMNS macro instead of the columns argument in all your functions. 此外,您在所有函数中使用的是COLUMNS宏而不是columns参数。

Obviously, if COLUMNS > columns , then you'll end up with a memory access violation at some point... 显然,如果COLUMNS > columns ,那么在某些时候您将遇到内存访问冲突...

The problem here is that the memory locations in your matrix are not contiguous. 这里的问题是矩阵中的存储位置不连续。 But in all your print/fill/sum matrix functions, you are assuming that they are. 但是在所有的打印/填充/求和矩阵函数中,您都假设它们是。

Assume a 2x2 matrix A. Your code will allocate memory in the following way. 假设一个2x2矩阵A。您的代码将以以下方式分配内存。 addr1 is starting address of one array, addr2 is of the second. addr1是一个数组的起始地址,addr2是第二个数组的起始地址。

A[0] addr1 (addr1+sizeof(int)) A [0] addr1(addr1 + sizeof(int))
A[1] addr2 (addr2+sizeof(int)) A [1] addr2(addr2 + sizeof(int))

But this is what you need: 但这是您需要的:

A[0] addr1 addr1 + sizeof(int) A [0] addr1 addr1 + sizeof(int)
A[1] (addr1 + 2*sizeof(int)) (addr1 + 3*sizeof(int)) A [1](addr1 + 2 * sizeof(int))(addr1 + 3 * sizeof(int))

So you need to replace your malloc statements into one single malloc: matrixA = malloc(r*s*sizeof(int)) Also, you are assuming that each row has COLUMN number of elements and not 's' number. 因此,您需要将malloc语句替换为一个malloc:matrixA = malloc(r * s * sizeof(int))此外,您假设每一行的元素数均为COLUMN,而不是's'。 If that's the case, you should malloc: matrixA = malloc(r*COLUMNS*sizeof(int)), but I am not sure why you need the other unused columns. 如果是这种情况,则应使用malloc:matrixA = malloc(r * COLUMNS * sizeof(int)),但我不确定为什么需要其他未使用的列。

Also, int matrix[ROWS][COLUMNS] seems to be unused. 另外,int matrix [ROWS] [COLUMNS]似乎未使用。

对malloc有问题,您正在尝试创建数组数组而不是2d数组,则应将其修复:

matrixA = malloc(r * c * sizeof(int)); // no any kind of additional for loop here, 1 malloc per matrix
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROWS 10
#define COLUMNS 10

void fillMatrix (int *matrix, int rows, int columns)
{
    int i, j;
    for(i = 0; i < rows; i++)
    {
        for(j= 0; j < columns; j++)
        {
            matrix[i * COLUMNS + j] = (rand() % 10) + 1;
        }
    }
}
void printMatrix (int *matrix, int rows, int columns)
{
    int i, j;
    for(i = 0; i < rows; i++)
    {
        for(j= 0; j < columns; j++)
        {
            printf("%2d ", matrix[ i * COLUMNS + j]);
        }
        printf("\n\n");
    }
}
void sumMatrix (int *matrix, int *matrixA, int *matrixB, int rows, int columns)
{
    int i, j;
    for(i = 0; i < rows; i++)
    {
        for(j= 0; j < columns; j++)
        {
            matrix[i * COLUMNS + j] = matrixA[i * COLUMNS + j] + matrixB[i * COLUMNS + j];
        }
    }
}

int main()
{
    int *matrixA = NULL, *matrixB = NULL, *matrixC = NULL;
    int matrix[ROWS][COLUMNS], r, s, i;
    srand((unsigned) time(NULL));
    do{
    printf("Rows and columns (min 1 1, max 10 10): ");
    scanf("%d %d", &r, &s);
    }while(r > ROWS || r < 1 || s > COLUMNS || s < 1);

    matrixA = malloc(COLUMNS*r * sizeof(int));

    printf("\nMatrix A:\n\n");
    fillMatrix(matrixA, r, s);
    printMatrix(matrixA, r, s);

    matrixB = calloc(r*COLUMNS,sizeof(int));

    printf("\nMatrix B:\n\n");
    fillMatrix(matrixB, r, s);
    printMatrix(matrixB, r, s);

    matrixC = calloc(r*COLUMNS, sizeof(int));

    printf("\nSummed up (Matrix C):\n\n");
    sumMatrix(matrixC, matrixA, matrixB, r, s);
    printMatrix(matrixC, r, s);

    free(matrixA);
    free(matrixB);
    free(matrixC);
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM