gpt4 book ai didi

c - main() 之外的 Scanf 段错误

转载 作者:行者123 更新时间:2023-11-30 19:51:34 25 4
gpt4 key购买 nike

我正在尝试生成一些任意维度的矩阵。我可以通过在 main 中调用 scanf 然后逐行分配矩阵元素来完成此操作,但尝试在 main 外部的单个函数中执行此操作(并且仅当在 main 外部调用 scanf() 时)给我一个段错误:

int **genmat(int nrow, int ncol){
int i,j;
int **mat = (int**) malloc(sizeof(int)*ncol*nrow);
char rowbuff[16];
for(i=0; i < nrow; i++){
INPUT: scanf("%[^\n]%*c",rowbuff);
if(strlen(rowbuff) != ncol){
printf("Error: Input must be string of length %d\n", ncol);
goto INPUT;
}
else{
for(j=0; j < ncol; j++){
if(rowbuff[j] == '1'){
mat[i][j] = 1;
}
else{
mat[i][j] = 0;
}
}
}
}
return(mat);
}

以下工作正常:

int *genrow(int ncol, char *rowbuff){
int i;
int *row = malloc(sizeof(int)*ncol);
for(i=0;i<ncol;i++){
row[i] = rowbuff[i]%2;
}
return(row);
}

在我的主函数中使用以下内容为矩阵的每一行调用 genrow() :

    for(i=0; i < row; i++){
INPUT: scanf("%[^\n]%*c",rowbuff);
if(strlen(rowbuff) != col){
printf("Error: Input must be string of length %d\n", col);
goto INPUT;
}
else{
int *newrow = genrow(col, rowbuff);
for(j=0; j < col; j++){
matrix[i][j] = newrow[j];
}
free(newrow);
newrow = NULL;
}
}

为什么这两种情况下的行为不同?

最佳答案

遗憾的是,动态分配的 2D 数组在 C 中既繁重又丑陋。要正确分配一个数组,非常重要的是一次调用 malloc 来完成此操作,就像您尝试做的那样。否则它不会是一个二维数组,而是一些分段的、缓慢的查找表。

但是,该 malloc 调用的结果将是指向 2D 数组的指针,而不是指向指针的指针。事实上,指针与 2D 数组没有任何关系 - 这是一个普遍但不正确的信念。

你应该做的是:

int (*mat)[nrow][ncol] = malloc( sizeof(int[nrow][ncol] );

这是一个指向二维数组的数组指针。这种语法已经有点繁琐了,更糟糕的是,将这个数组指针传递回 main 并不容易,因为它是一个本地指针变量。所以你需要使用一个指向数组指针的指针......并且没有很好的方法来做到这一点。事情是这样的:

void genmat (size_t nrow, size_t ncol, int (**mat)[nrow][ncol] )
{
*mat = malloc( sizeof(int[nrow][ncol]) );

为了稍微简化使用,您可以创建一个指向行的临时指针,这不需要多层间接,因此更容易使用:

  int (*matrix)[ncol] = *mat[0]; // in the pointed-at 2D array, point at first row

for(size_t r=0; r<nrow; r++) // whatever you want to do with this matrix:
{
for(size_t c=0; c<ncol; c++)
{
matrix[r][c] = 1; // much more convenient syntax than (**mat)[r][c]
}
}

从 main 中,您必须像这样调用代码:

size_t row = 3;
size_t col = 4;

int (*mat)[row][col];
genmat(row, col, &mat);
<小时/>

示例:

#include <stdio.h> 
#include <stdlib.h>


void genmat (size_t nrow, size_t ncol, int (**mat)[nrow][ncol] )
{
*mat = malloc( sizeof(int[nrow][ncol]) );
int (*matrix)[ncol] = *mat[0];

for(size_t r=0; r<nrow; r++)
{
for(size_t c=0; c<ncol; c++)
{
matrix[r][c] = 1;
}
}
}

void printmat (size_t nrow, size_t ncol, int mat[nrow][ncol])
{
for(size_t r=0; r<nrow; r++)
{
for(size_t c=0; c<ncol; c++)
{
printf("%d ", mat[r][c]);
}
printf("\n");
}
}

int main (void)
{
size_t row = 3;
size_t col = 4;

int (*mat)[row][col];
genmat(row, col, &mat);

printmat(row, col, *mat);

free(mat);
return 0;
}

请注意,实际代码需要解决 malloc 返回 NULL 的情况。

关于c - main() 之外的 Scanf 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41013815/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com