将指针/数组从函数

时间:2017-04-09 01:39:03

标签: c pointers dynamic-arrays

我正在学习函数/指针,并且遇到了一些问题。我需要写的是一个带有main()的C程序和另外两个函数。

要求:

  1. read_funct()必须使用malloc()分配足够的内存来存储数据。

  2. read_funct 的函数原型必须

    int read_funct(int *data_num, double **data_vals, char *filename)
    
  3. 如何工作:

    1. main()调用第一个函数:read_funct()

    2. read_num()从文件中读取二进制数据。必须提取两个值:no。值(前4个字节),然后是值本身(每个8个字节,因此包含在下一个8 *值的值中)。这些对应于data_numdata_vals。必须打印它们,然后程序返回main()

    3. main()执行操作以编辑第一个文件中的数据。

    4. main()调用第二个函数:write_funct(),将编辑后的数据写入新文件。

    5. 我在哪里:

      第一个函数正确读取data_num,并读取/打印data_vals。这一切都正常。但是,我正在尝试在main()中打印这些内容以验证我是否正在对正确的数据执行操作,但我无法使其正常工作。

      注意:我现在不是想让它与write_funct()一起使用,只是一步一步地进行。

      以下是main()的当前代码:

      int read_funct(int *data_num, double **data_vals, char *filename);
      int main()
      {
        int data_num;
        double **data_vals;
      
        //Reads file using read_funct()
        read_funct(&data_num, data_vals, filename);
      
        //Check: print data_num
        printf("\nCheck No. of Values: %d\n", data_num);
      
        //Check: print data_vals
        for(int i = 0; i<data_num; i++)
        {
              printf("%0.3lf\t", data_vals[i]);
        }
        return(0);
      }
      

      这是read_funct(

      int read_funct (int *data_num, double **data_vals, char *filename)
      {
          FILE * fp = fopen(filename, "rb");                          //Opening file      
         //There's code here to check valid file open
      
         //There's code here to determine size and check valid length
      
        //Proceed with reading data_num if file is large enough
        char buffer_n[4];
        fread(buffer_n, 4, 1, fp);
        int res = buffer_n[0]|(buffer_n[1] << 8)|(buffer_n[2] << 16)|(buffer_n[3] << 24);     //Convert endian
      
        data_num = &res;          //Passes results back to data_num
        printf("Number of Data Values: %d \n", *data_num);    //Printing results
      
        //Proceeds with calculating data_vals
        data_vals = malloc(8*res);                //Allocating memory
        fread(data_vals, 8, res, fp); 
      
          //Prints data_vals
          for(int i=0; i<res; i++)
          {
              printf("%0.3f\t", data_vals[i]);
          }
          printf("\nEnd of File Read.\n\n");
          fclose(fp); 
          free(data_vals);                //Free allocated memory
          return(0);
      }
      

      所需的输出:

      基本上,我希望它打印出来自read_file()内部的值,然后在main()中打印一个检查,因此输出将类似于:

      No. of values: 3            //From printf in read_file()
      2 4 6
      
      Check No. of values: 3      //From printf in main()
      2 4 6
      

      我认为我错了:

      1. 相当确定的主要问题是我搞砸了我的指针以及我是如何在main()初始化的。我一直在努力解决这个问题,但我认为我需要一些更有经验的帮助来解决这个问题。

      2. 我知道每个malloc()来电都必须有free(),但是我担心这样做的方式可能就像我一样,也许我已经做到了无法在main()中检索它。是否需要有一个分配内存的中间缓冲区?

      3. 非常感谢帮助使此代码正常工作。谢谢!

2 个答案:

答案 0 :(得分:6)

除了过早释放数据外,您还有另一个问题:

double **data_vals;
read_funct(&data_num, data_vals, filename);

如果您希望函数填充(写入,修改)data_vals,则必须传递其地址,就像使用data_num一样。

这是另一个略有不同的解释。你看,你声明data_vals但你没有给它赋值 - 它包含垃圾。因此,将data_vals传递给任何函数或在任何表达式中使用它都是没有意义的。它有一种感觉分配某些东西,通过直接赋值或将其地址传递给函数,以便填充函数变量。

然后,您对data_vals的使用描绘了一个向量或一个数组。所以你真的需要声明一个带[]的数组,或者可能是一个指针(指针和数组在C中非常相关/可互换)。 main()函数的逻辑需要一个指针,而不是指向的指针。因此,这是合适的:

double *data_vals;

写入指针变量的函数需要写入变量的地址;换句话说:一个指向指针的指针。这就是您的函数具有此(正确)签名的原因:

read_funct(..., double **data_vals, ...)

为了便于理解,让我们看看你写的另一个(更简单)的东西:

int data_num;
read_funct(&data_num, ...);  // declaration: read_funct(int *data_num, ...)

您在main()中将data_num声明为整数;使用指向整数的形式参数声明read_funct(),然后调用read_funct()传递变量data_num的地址。完善。现在,对另一个变量data_vals执行相同的操作。您将其声明为指向double 的指针,使用符号&data_vals将其地址传递给read_funct(),并且您的函数read_funct()将该参数声明为指向double的指针的 (并使用*data_vals = ...写入。您可以看到两个变量之间的并行性,对吗?

可能是我太迂腐了,但你的问题非常清楚,形成得很好,所以我也尝试过这样做。

答案 1 :(得分:4)

是的,你过早地释放缓冲区了。在释放它之后,不能保证它包含什么。你最后可以在主页上释放它。