动态分配2d数组函数

时间:2016-11-28 21:49:45

标签: c function dynamic-allocation

所以我有一个c结构的程序,有3个文件:main,alloc.h和alloc.c:  在主要我有一个指向另一个指针的指针的deccalaration我打算分配一个n * m数组:

#include <stdio.h>
#include <stdlib.h>
#include "alloc.h"
int main()
{
   int **mat,n,m;
   alloc_matrix(&mat,int &n,int &m);
   return 0;
}

在alloc.c中,我有以下声明:

#ifndef ALLOC_H_INCLUDED
#define ALLOC_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
void alloc_matrix(int***,int*,int*);

#endif

在alloc.c中我有函数:

void alloc_matrix(int ***mat,int *n,int *m)
{
    printf("\nn = "); scanf("%d", n);
    printf("\nm = "); scanf("%d", m);
    *mat = (int**)calloc(*n,sizeof(int*));
    int i;
    for(i = 0; i < *n; i++)
    *(mat+i) = (int*)calloc(*m,sizeof(int));
}

但该程序不起作用。它进入某种循环并且不会结束。  如果我在main中分配它,它会起作用,但我不知道我在alloc函数中做错了什么。

2 个答案:

答案 0 :(得分:2)

这是正确的代码。您的错误是在alloc_matrix的定义中,您在分配循环中使用了*(mat+i),它应该是*(*mat+i),因为mat是int***所以基本地址是2D数组将在*mat中。然后你需要移动偏移i,然后取消引用1D数组的内存位置。

主:

#include <stdio.h>
#include <stdlib.h>
#include "alloc.h"
int main()
{
   int **mat,n,m;
   alloc_matrix(&mat,&n,&m);
   return 0;
}

alloc.h

#ifndef ALLOC_H_INCLUDED
#define ALLOC_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
void alloc_matrix(int***,int*,int*);

#endif

alloc.c:

void alloc_matrix(int ***mat,int *n,int *m)
{
    printf("\nn = "); scanf("%d", n);
    printf("\nm = "); scanf("%d", m);
    *mat = (int**)calloc(*n,sizeof(int*));
    int i;
    for(i = 0; i < *n; i++)
    *(*mat+i) = (int*)calloc(*m,sizeof(int));
}

读取功能的代码:

void read_matrix(int ***mat,int n,int m)
    {
      int i,j;
      for(i = 0; i < n; i++)
       for(j = 0; j < m; j++)
        {
          printf("mat[%d][%d] = ", i, j);
          scanf("%d", (*(*mat+i))+j);
        }
    }

问题在于它只读取第一行并冻结。

答案 1 :(得分:0)

void alloc_matrix(int ***mat,int *n,int *m)

这一行有两个问题。两者都不致命,但两者都值得一试。

第一个问题:此程序中的矩阵表示为int**。为什么alloc_matrix接受int***?分配内容的所有标准函数(malloc和friends)都返回指向该内容的指针。这是用C语言做事的惯用方法。它减少了你的星数(作为一个三星级的C程序员不是一个值得骄傲的成就)并简化了代码。该功能应更改为

int** alloc_matrix( // but what's inside the () ?

第二个问题是,为什么名为alloc_matrix的函数会提示用户并读取值?这些事情与分配无关。一个函数应该做一件事,做得好。 malloc是否会提示您输入尺寸? fopen是否提示您输入文件名?这些东西将被视为第一学位的废话,这是正确的。建议读取其他地方的大小并将它们作为输入参数传递给alloc_matrix。因此,

int** alloc_matrix(int n, int m) { // but what's inside the {}?

alloc_matrix的剩余部分很简单:

int** alloc_matrix(int n, int m) {
  int** mat; // that's what we will return
  int i;
  mat = (int**)calloc(n, sizeof(int*));
  for(i = 0; i < n; i++)
     // here comes the important part.

由于我们简化了alloc_matrix并减少了mat中的星数,我们应该如何处理旧的循环体?那是:

    *(mat+i) = (int*)calloc(...);

但是如果我们移除一颗星星就会变成

    (mat+i) = (int*)calloc(...);

这是一个明显的废话。也许旧线是一个问题。它引发编译器警告的事实当然不代表它的正确性。那么如何纠正呢?没有太多选择。事实证明,为了恢复理智,我们必须保留旧的左手边(为三星mat编写)。或者,更好的是,使用等效但更惯用的符号:

    mat[i] = (int*)calloc(m, sizeof(int));

所以整个功能现在变成了

int** alloc_matrix(int n, int m) {
  int **mat;
  int i;
  mat = (int**)calloc(n, sizeof(int*));
  for(i = 0; i < n; i++)
    mat[i] = (int*)calloc(m, sizeof(int));
  return mat; 
}

它应该被称为

mat = alloc_matrix(n, m);

通常说人们不应该投射calloc和朋友的结果。但在这种情况下,演员已启用警告,这有助于找到错误。我现在要离开演员了。