C 程序在运行时终止
以下是将两个矩阵相乘的代码。当我尝试输入数组元素时,它会在运行时停止。我为重复的任务创建了不同的函数,因此它变得模块化,易于理解和调试C 程序在运行时终止,c,arrays,data-structures,C,Arrays,Data Structures,以下是将两个矩阵相乘的代码。当我尝试输入数组元素时,它会在运行时停止。我为重复的任务创建了不同的函数,因此它变得模块化,易于理解和调试 #include<stdio.h> #include<stdlib.h> void input(int *rows, int *columns); //Inputs rows and columns void allocate(int **arr, int rows, int columns); //A
#include<stdio.h>
#include<stdlib.h>
void input(int *rows, int *columns); //Inputs rows and columns
void allocate(int **arr, int rows, int columns); //Allocates memory for the array
void initialize(int **arr, int rows, int columns); //Initializes(rather, declares because calloc initializes to zero) the array
void release(int **arr, int rows); //Frees the dynamically allocated memory
int main(void)
{
int **matrix1, **matrix2, **product, rows1, rows2, columns1, columns2, i, j;
printf("\nEnter rows and columns of first matrix\n");
input(&rows1, &columns1);
allocate(matrix1, rows1, columns1);
printf("\nEnter rows and colummns of second matrix\n");
input(&rows2, &columns2);
allocate(matrix2, rows2, columns2);
if(columns1 != rows2)
{
printf("Matrix cannot be multiplied!");
exit(0);
}
printf("\nEnter the contents of matrix 1\n");
计划的其余部分如下:
printf("\nEnter the contents of matrix 2\n");
initialize(matrix2, rows2, columns2);
initialize(product, rows1, columns2);
for(i = 0; i < rows1; i++)
for(j = 0; j < columns2; j++)
for(int k = 0; k < columns1; k++)
product[i][j] = product[i][j] + matrix1[i][k] * matrix2[k][j];
for(i = 0; i < rows1; i++)
{
for(j = 0; j < columns2; j++)
printf("%d ", product[i][j]);
printf("\n");
}
release(matrix1, rows1);
release(matrix2, rows2);
release(product, rows1);
}
函数的作用是:动态地将内存分配给矩阵。首先它为int*类型分配内存,然后为int类型分配内存。它还通过将内存与NULL进行比较来检查内存是否正确分配
void allocate(int **arr, int rows, int columns)
{
arr = (int**)calloc(rows, sizeof(int*));
if(arr == NULL)
{
printf("Memory Allocation Failed!");
exit(1);
}
for(int i = 0; i < rows; i++)
{
arr[i] = (int*)calloc(columns, sizeof(int));
if(arr[i] == NULL)
{
printf("Memory Allocation Failed!");
exit(1);
}
}
}
void分配(int**arr,int行,int列)
{
arr=(int**)calloc(rows,sizeof(int*);
如果(arr==NULL)
{
printf(“内存分配失败!”);
出口(1);
}
对于(int i=0;i
函数的作用是:输入数组的元素程序运行正常,直到达到此功能。当我输入数组元素并按enter键时,程序终止,出现一个对话框,其中显示:一个问题导致程序停止正常工作。Windows将关闭该程序并通知是否有可用的解决方案
void初始化(int**arr,int行,int列)
{
对于(int i=0;i
函数的作用是释放动态分配的内存
void release(int **arr, int rows)
{
for(int i = 0; i < rows; i++)
free(arr[i]);
free(arr);
}
void release(整数**arr,整数行)
{
对于(int i=0;i
您没有使用allocate
函数初始化这些指针,那么您就是在未初始化的内存上进行分段
void release(int **arr, int rows)
{
for(int i = 0; i < rows; i++)
free(arr[i]);
free(arr);
}
要使代码在最少更改的情况下工作,您可以使用三星指针:
void allocate(int ***arr, int rows, int columns)
{
*arr = (int**)calloc(rows, sizeof(int*));
if(*arr == NULL)
{
printf("Memory Allocation Failed!");
exit(1);
}
for(int i = 0; i < rows; i++)
{
(*arr)[i] = (int*)calloc(columns, sizeof(int));
if((*arr)[i] == NULL)
{
printf("Memory Allocation Failed!");
exit(1);
}
}
}
int ** allocate(int rows, int columns)
{
int **arr = calloc(rows, sizeof(int*));
if(arr == NULL)
{
printf("Memory Allocation Failed!");
exit(1);
}
for(int i = 0; i < rows; i++)
{
arr[i] = (int*)calloc(columns, sizeof(int));
if(arr[i] == NULL)
{
printf("Memory Allocation Failed!");
exit(1);
}
}
return arr;
}
但这很难解释。更正确的答案是重新组合allocate
函数以返回所需的数组:
void allocate(int ***arr, int rows, int columns)
{
*arr = (int**)calloc(rows, sizeof(int*));
if(*arr == NULL)
{
printf("Memory Allocation Failed!");
exit(1);
}
for(int i = 0; i < rows; i++)
{
(*arr)[i] = (int*)calloc(columns, sizeof(int));
if((*arr)[i] == NULL)
{
printf("Memory Allocation Failed!");
exit(1);
}
}
}
int ** allocate(int rows, int columns)
{
int **arr = calloc(rows, sizeof(int*));
if(arr == NULL)
{
printf("Memory Allocation Failed!");
exit(1);
}
for(int i = 0; i < rows; i++)
{
arr[i] = (int*)calloc(columns, sizeof(int));
if(arr[i] == NULL)
{
printf("Memory Allocation Failed!");
exit(1);
}
}
return arr;
}
奖金错误:
你根本没有为
产品
数组调用allocate
,这也(通常)会导致segfault。我想应该是scanf(“%d”,arr[I][j])代码>在初始化
函数中(注意缺少的符号(&
))。Rahul Bharadwaj我同意这些问题是由于scanf()中缺少符号而发生的,但是在这种情况下,我已经将符号放在了一起,仍然会出现运行时错误。出于您自己的理解,我建议为所有函数添加一个接口描述。执行此操作时,您会发现voidallocate(int**arr,int行,int列)
的设计是错误的。因此,您希望获得指向int*
的指针。第一个错误:您没有使用返回值作为结果,这使得函数的使用更加困难。第二个错误:由于行为没有明确的文档记录,您没有注意到参数arr
在第一行被覆盖。您的目的可能是将calloc
的返回值保存到*arr
--用法:int*allocate(int行,int列)
harper我不明白你的意思。如果您能再详细说明一下,我将不胜感激。第二件事是,为什么我不能按原样使用函数allocate?它应该可以工作,因为在函数调用期间,我将matrix1的地址发送到arr1,然后分配内存。因此,它应该反映在原始变量中,即matrix too(int**)calloc(rows,sizeof(int*)
不需要强制执行malloc的返回,这是不必要的。见:但int***arr*arr=(int**)calloc(rows,sizeof(int*)代码>和int**arr;arr=(int**)calloc(rows,sizeof(int*)代码>在效果上是相同的不,它们不是。第一个通过指向main
提供的int**
的指针写入。第二个写入main提供的int**
副本。你看到区别了吗?在您的allocate
版本中,您只是从main
复制int**
。main
中的int**
s永远不会更改。更好的选择是:将类型更改为int**
,并返回指向已分配指针块的指针。始终避免成为一名三星级程序员(这不是一种恭维),但有时这是不可避免的(不像这里)。您可以使用取消引用的指针来设置类型大小,例如int**arr=calloc(rows,sizeof*arr)代码>和arr[i]=calloc(列,sizeof*a[i])代码>这样做,你永远不会弄错你的字体大小。@DavidC.Rankin这和我在回答中说的不同吗?我没有更改calloc调用,因为我试图最小化与原始代码的偏差,这些偏差与问题没有直接关系。@GulshanMishra在C中调用函数时,函数会收到函数参数的副本。如果将int
作为参数传递,函数将收到该int
的副本。函数中对该int
所做的任何工作都不会反映在原始调用方的副本中。您的int**
s的情况完全相同。
int ** allocate(int rows, int columns)
{
int **arr = calloc(rows, sizeof(int*));
if(arr == NULL)
{
printf("Memory Allocation Failed!");
exit(1);
}
for(int i = 0; i < rows; i++)
{
arr[i] = (int*)calloc(columns, sizeof(int));
if(arr[i] == NULL)
{
printf("Memory Allocation Failed!");
exit(1);
}
}
return arr;
}
matrix1 = allocate(rows1, columns1);