c - 使用指针将二维数组传递给函数
问题描述
谁能解释 print() 函数有什么问题?
printf("Control") 从不工作,输出是分段错误 11
int main(int argc, char **argv){
int m=5,n=4; // matrix[5][4]
int a=50,b=20; // range: 20-50
int **matrix;
imatrix(matrix,m,n,a,b);
print(matrix,m,n);
第一步:用值填充地址
void imatrix(int **matrix,int m,int n,int max, int min){
srand(time(NULL));
int i=0,j=0;
matrix = (int **)malloc( m * sizeof(int*) );
if( matrix == NULL ){
printf( "memory req.!" );
}
for( i = 0; i < m; i++ ) {
matrix[i] = (int *)malloc( n * sizeof(int) );
if( matrix[i] == NULL ){
printf( "memory req.!" );
}
}
for(i=0;i<m;i++){
for(j=0;j<n;j++){
matrix[i][j]=(rand()%(max-min))+min;
printf("%2d ",matrix[i][j]);
}
printf("\n\n");
}
}
到这里为止一切都很好。我得到分段错误:下面的代码和“控制”行之后的 11 永远不起作用
void print(int **matrix, int m, int n){
int i,j;
for(i=0; i < m; i++){
for(j=0; j < n; j++){
printf("%d",*(*(matrix + i) + j));
}
printf("\n");
}
printf("control");
}
解决方案
这不是printf("control")
which segfaults (尽管你最好不要使用printf
它:考虑将其更改为puts("control")
,这也会输出换行符。)这是之前打印矩阵的尝试,它正在取消引用未初始化的值。
发生这种情况是因为您的imatrix
函数没有返回它创建的矩阵,并且matrix
您的 inmain
没有任何值。
事实上,imatrix
不返回任何东西,因为它被定义为返回void
。它需要一个matrix
参数,我想它是一个输出参数,但是:
该参数的类型错误,无法作为输出参数(输出参数必须是指向要返回的对象的指针;)
它从不尝试使用指向要返回的对象的指针来返回对象。
为了符合这些要求,您需要原型
void imatrix(int*** matrix, int m, int n, int max, int min);
并且您必须为matrix
[注 1] 的每次使用添加一个额外的间接级别:
*matrix = malloc(m * sizeof(**matrix));
if (*matrix == NULL) {
printf( "memory req.!" );
/* NOTE: You shouldn't attempt to continue after the malloc fails.
* Return immediately and let the caller deal with the malloc failure.
*/
}
for( i = 0; i < m; i++ ) {
(*matrix)[i] = malloc( n * sizeof(*(*matrix)[i])) );
if( (*matrix)[i] == NULL ){
// etc.
我认为我们可以同意这是一个主要的 PITA,除非必要,否则不值得麻烦。
就个人而言,我发现除非绝对必要,否则根本不使用输出参数不会让人感到困惑。在这种情况下,根本没有必要,因为您可以只返回指针来分配内存:
/* CHANGE: Prototype */
int** imatrix(int m, int n, int max, int min){
srand(time(NULL)); /* TODO: This initialisation should really be done in main */
int i=0, j=0;
/* CHANGE: matrix is a local variable */
int** matrix = malloc( m * sizeof(*matrix) );
/* CHANGE: Immediate return on malloc failure */
if( matrix == NULL ) {
return matrix;
}
for( i = 0; i < m; i++ ) {
matrix[i] = malloc( n * sizeof(*matrix[i]) );
if( matrix[i] == NULL ){
printf( "memory req.!" );
}
}
for(i=0;i<m;i++){
for(j=0;j<n;j++){
matrix[i][j]=(rand()%(max-min))+min;
printf("%2d ",matrix[i][j]);
}
printf("\n\n");
}
/* CHANGE: matrix is returned */
return matrix;
}
这有一个稍微不同的使用模式:
int main(int argc, char **argv){
int m=5, n=4; // matrix[5][4]
int a=50, b=20; // range: 20-50
/* CHANGE: imatrix returns the new matrix */
int **matrix = imatrix(m, n, a, b);
/* CHANGE: check for failure */
if (matrix == NULL) {
fprintf(stderr, "%s\n", "imatrix failed to allocate memory.");
exit(1);
}
print(matrix, m, n);
/* TODO: Free the storage allocated for matrix */
}
笔记
在这段代码中,我改变了 malloc 的用法:
lvalue = (RedundantCast*)malloc(count * sizeof(FixedType));
到惯用 C:
lvalue = malloc(count * sizeof(*lvalue));
的返回值的显式转换
malloc
在 C 中充其量是没有意义的,因为malloc
返回 avoid*
并且 C 很乐意自动将 avoid*
转换为任何类型的指针。使用目标 ( ) 指向的对象的类型sizeof(*lvalue)
而不是插入特定类型可以保护您免受类型在未来编辑中更改的可能性,并且您忘记在所有调用中进行更改malloc
。(例如,考虑如果您决定制作matrix
一个矩阵long long
而不是会发生什么int
。)
推荐阅读
- scala - scala,过滤RDD
- python - Apriori算法的输出是否应该是一对一的关系
- git - 从存储库获取分支依赖
- system - 如何使用 Windows 防火墙阻止进程?
- spring-boot - Jprofiler 不会在应用程序崩溃时分离
- c++ - 我可以使用 cmake/make 编译所有且仅编译我使用的 cpp/hpp 文件吗?
- r - 如何解决这个与原子向量有关的 R 错误消息?
- javascript - 无法在 Angular 7 中使用 D3 条形图读取未定义的属性“地图”
- google-app-maker - 如何通过代码样式化不同类型输入控件的值?
- deep-learning - 在 OpenNMT-py 中的翻译过程中获得对齐/注意