Scanf Segfaults在main()之外

时间:2016-12-07 09:31:36

标签: c linear-algebra

我试图生成一些任意维度的矩阵。我可以通过在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);
}

在我的main函数中有以下内容为矩阵的每一行调用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;
        }
    }

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

2 个答案:

答案 0 :(得分:0)

动态分配的2D数组很遗憾在C中是繁琐和丑陋的。要正确分配一个,使用单次调用malloc 来执行此操作非常重要,就像您尝试的那样。否则它不会成为2D数组,而是一些分段的慢速查找表。

但是,malloc调用的结果将是指向2D数组的指针,而不是指向指针的指针。实际上,指针指针与2D数组无关 - 这是一种普遍但不正确的信念。

你应该做的是:

at 06:00 -m -f ~/scheduledTask.sh

这是指向2D数组的数组指针。这种语法已经有点麻烦了,但是为了使事情变得更糟,将这个数组指针传递回main是不容易的,因为它是一个本地指针变量。所以你需要使用一个指向数组指针的指针......并且没有办法做到这一点。它是这样的:

namespace App\Http\Middleware;

use Closure;

class CorsMiddleware
{
    public function handle($request, Closure $next)
    {
        $headers = [
            'Access-Control-Allow-Origin'      => '*',
            'Access-Control-Allow-Methods'     => 'POST, GET, OPTIONS',
            'Access-Control-Allow-Credentials' => 'true',
            'Access-Control-Max-Age'           => '86400',
            'Access-Control-Allow-Headers'     => 'Content-Type, Authorization, X-Requested-With'
        ];

        if ($request->isMethod('OPTIONS')) {
            return response()->json('{"method":"OPTIONS"}', 200, $headers);
        }

        $response = $next($request);
        foreach($headers as $key => $value) {
            $response->header($key, $value);
        }

        return $response;
    }
}

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

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]
    }
  }

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

答案 1 :(得分:-1)

我认为问题出在int **mat = (int**) malloc(sizeof(int)*ncol*nrow); 您正在尝试分配2D数组吗?但这不是分配内存的正确方法。你不能简单地分配整块内存。 你应该在这里做的是,为所有行分配内存(基本上是指向存储列地址的指针),然后为列分配

int **mat= (int **)malloc(nrow * sizeof(int *));
for (i=0; i<nrow; i++)
     mat[i] = (int *)malloc(ncol * sizeof(int));

请参阅此链接以获取更多信息http://www.geeksforgeeks.org/dynamically-allocate-2d-array-c/