【问题标题】:Segmentation fault (2D array with dynamic memory allocation) in CC中的分段错误(具有动态内存分配的二维数组)
【发布时间】:2014-06-15 19:26:34
【问题描述】:

我仍然熟悉使用 malloc、calloc 或 realloc。可以肯定的是,由于指针不正确或其他原因,我会遇到分段错误,但是对于我的一生,我不明白我在哪里做错了。该程序在用户输入为“5 5”时工作,除此之外的任何其他内容都会导致程序行为怪异,并且经常因分段错误而失败。矩阵 A 和 B 应该填充随机数,矩阵 C 应该对矩阵 A 和 B 求和,同时使用动态内存分配。我不熟悉 allocs,我刚刚开始了解指针和 2D 数组。有人可以解释我做错了什么。这是整个代码。

#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;
}

【问题讨论】:

  • 我认为矩阵 A、B 和 C 的类型为 int** (int **matrixA = NULL, **matrixB = NULL, **matrixC = NULL;)

标签: c arrays pointers dynamic allocation


【解决方案1】:

这里的问题是矩阵中的内存位置不连续。但是在所有打印/填充/求和矩阵函数中,您都假设它们是。

假设一个 2x2 矩阵 A。您的代码将按以下方式分配内存。 addr1 是一个数组的起始地址,addr2 是第二个数组。

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

但这正是你需要的:

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

因此,您需要将 malloc 语句替换为一个 malloc: 矩阵A = malloc(r*s*sizeof(int)) 此外,您假设每行都有 COLUMN 个元素而不是“s”个数。如果是这种情况,你应该 malloc: matrixA = malloc(r*COLUMNS*sizeof(int)),但我不确定您为什么需要其他未使用的列。

另外,int matrix[ROWS][COLUMNS] 似乎没有使用。

【讨论】:

  • 哦,我现在明白了。谢谢你为我画了一幅画!最后的论点是完全有效的,我忘了删除那行。再次,非常感谢!
【解决方案2】:

您将所有矩阵作为一维数组访问,因此应该相应地分配它们。

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

仅此而已;无需执行for (i = 0; i &lt; r; i++) 循环。

此外,您在所有函数中都使用COLUMNS 宏而不是columns 参数。

显然,如果COLUMNS &gt; columns,那么你最终会在某个时候遇到内存访问冲突......

【讨论】:

  • 仍然遇到同样的错误。你能在你的机器上测试代码并输入“3 3”吗?它崩溃了……尽管我已经尝试过了,上面编写的代码是我摆弄 malloc 和 calloc 的结果。问题仍然存在。附言将我的代码更改为此实际上也会导致它现在在“5 5”时崩溃。
  • @VengeanceIsMine:你摆脱了for (i = 0; i &lt; r; i++) 循环吗?
  • 可以,例如:int* matrixA = malloc(r * s * sizeof(int)); printf("\n矩阵 A:\n\n");填充矩阵(矩阵A,r,s); printMatrix(matrixA, r, s);
  • @VengeanceIsMine:您正在使用预处理器定义 COLUMNS 而不是所有函数中的参数列!!!您需要更改它(添加到上面的答案中)。
  • 好的,试过了,还是不行。一定是误会了你,但问题仍然存在。使用了 BLUEPIXY 的代码,现在可以了。还是谢谢你!
【解决方案3】:
#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;
}

【讨论】:

  • 这个对我有用。你能不能用通俗的话向我解释一下什么以及为什么应该被替换。
  • @VengeanceIsMine 你在数组的处理上搞混了。我的答案统一为一维数组。
  • @VengeanceIsMine ,我认为将COLUMNS 替换为scolumns 比较好,因为这很浪费内存。
  • 没错,我就是因为这个才改的。感谢您的意见。
【解决方案4】:

malloc 有问题,您正在尝试创建数组数组而不是二维数组,您应该修复它:

matrixA = malloc(r * c * sizeof(int)); // no any kind of additional for loop here, 1 malloc per matrix

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-27
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 2013-09-04
    • 2017-05-07
    • 2015-11-11
    • 2020-08-08
    相关资源
    最近更新 更多