我应该如何处理未处理的异常

时间:2021-04-04 09:05:58

标签: c unhandled

我尝试了很多事情,但它仍然显示我相同的情况,即存在未处理的异常:VS 中的访问冲突写入位置。但是当我对一维数组进行排序时不会发生这种情况。接下来我可以尝试什么?

int main(void) {
   static int a[3][4]{}, ab[3][4]{};
   int i, j, k, N, M;
   int* a1=nullptr;
   printf("Matrica mora da ima velicinu 3 sa 4\n");
   printf("Enter the order \n\n\t");
   scanf_s("%d%d",&N ,&M);
 for (i = 0;i < M;++i)
{
    for (j = 0;j < N;++j)
    {
        scanf_s(" %d", &a[i][j]);
        ab[i][j] = a[i][j];
    }
    printf("\n");
}

for (i = 0;i < M;++i) {

    for (j = 0;j < N;++j) {

        printf(" %d", a[i][j]);

    }

    printf("\n ");
}
    
//classic sorting
for (i=0; i < M; ++i)
{
    for (j = 0;j < N;++j)
    {
        for (k = j + 1;j < N;++k)
            if (a[i][j] > a[i][k])
            {
                *a1 = a[i][j]; // there is exception thrown
                a[i][j] = a[i][k];
                a[i][k] = *a1;
            }
    }
}

1 个答案:

答案 0 :(得分:0)

首先,数组的静态分配存在问题,但是在用户输入 NM 后没有清理它们。这意味着您只分配了一个 3x4 矩阵,但用户可以输入和写入任何维度的矩阵(例如 10x10),这可能会导致访问冲突。

我建议对输入值进行卫生处理,例如

// It's always better to have limits as constant.
const int MAX_N = 3;
const int MAX_M = 4;
static int a[MAX_N][MAX_M];
...

scanf_s("%d%d",&N ,&M);

// Check if the dimensions can be fitted into the statically allocated array.
if(N > MAX_N || N <= 0 || M > MAX_M || M < 0)
{
    // indicate invalid dimensions, either by returning from main with -1
    // or calling exit(-1), or throwing an exception.
    return -1;
}

如果输入没有超过 3x4,另一件事可能有问题 - i0 变为 M,而不是 N (我所期望的),这也可能是有问题的。 C/Cpp 中矩阵寻址的工作方式是将矩阵线性化为数组,使用 a[i][j] 访问它会导致使用 a[i*MAX_J + j] 访问数组。在您的情况下,该数组具有 12 元素(3x4)和 MAX_J=4,因此使用反向索引集 a[4][3] 访问它将访问 a[4*4+3]=a[19],它将从数组外部访问内存。

关于访问冲突写入问题,未分配 a1,因此当您尝试执行 *a1= ... 时,您正在写入 nullptr,这是一个受保护的地址,因此访问写作时违反。解决这个问题的方法是:

  • a1 成为 int 变量(不是指针)
  • 首先通过执行 a1a1 = malloc(sizeof(int)); 分配内存,然后在使用 free(a1) 后释放它(但由于它只是一个元素,我建议转换 a1改为int
  • 分配矩阵元素的地址,如a1=&a[i][j],但在您的情况下这在逻辑上是无效的(之后,您写入指针指向的位置,因此原始值将丢失) .

一维数组没有发生这种情况的原因可能是因为维度颠倒了 - 矩阵可能是 1x4,但是您将以 4x1 的形式访问它,并且您正在对所有内容进行排序j 索引从 01 的值,并且由于只有一个值,因此您不会进入 k 循环。