我尝试了很多事情,但它仍然显示我相同的情况,即存在未处理的异常: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;
}
}
}
答案 0 :(得分:0)
首先,数组的静态分配存在问题,但是在用户输入 N
和 M
后没有清理它们。这意味着您只分配了一个 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
,另一件事可能有问题 - i
从 0
变为 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
变量(不是指针)a1
为 a1 = malloc(sizeof(int));
分配内存,然后在使用 free(a1)
后释放它(但由于它只是一个元素,我建议转换 a1
改为int
)a1=&a[i][j]
,但在您的情况下这在逻辑上是无效的(之后,您写入指针指向的位置,因此原始值将丢失) .一维数组没有发生这种情况的原因可能是因为维度颠倒了 - 矩阵可能是 1x4
,但是您将以 4x1
的形式访问它,并且您正在对所有内容进行排序j
索引从 0
到 1
的值,并且由于只有一个值,因此您不会进入 k
循环。