【问题标题】:how to return float array from a function?如何从函数返回浮点数组?
【发布时间】:2016-06-21 00:25:47
【问题描述】:

输出将k 的值显示为0.000,但它应该包含从funcTest() 返回的实际值。

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

float *funcTest(int *a, int size)
{
    float p[size];
    int i;
    for(i=0; i< size; i++){
        p[i] = *a;
        p[i]=p[i]/2;
        a++;
    }
    for(i =0; i<size; i++){
        printf("%f\n",p[i]);
    }
    return (float *)p;
}

int main()
{
    int a[4] = {1,5,3,7};
    int size = 4;
    int i,j;
    float *k;
    k = funcTest(&a[0],size);
    for(i =0; i<size; i++){
        printf("%f\n",*k);
        k++;
    }
    return 0;
}

输出:

0.5
2.5
1.5
3.5
1.5
0.000
0.000
0.000

【问题讨论】:

  • p 将在您离开方法“functest”后被销毁。因此,您收到的指针根本无效。

标签: c arrays function pointers return


【解决方案1】:

您返回一个局部变量。因此,在函数结束时,局部变量被清除并且不再存在。你应该使用malloc

float *funcTest(int *a, int size)
{
    float *p = malloc(sizeof(float) * size);

当您不再使用 free 时,不要忘记释放内存。如果忘记了,就会发生内存泄漏

【讨论】:

    【解决方案2】:

    在您的代码中,float p[size]; 是函数 funcTest() 的本地地址,因此您不能从函数返回它的地址并期望它在调用者中有效。一旦funcTest() 函数结束,p 将不复存在。那么,任何使用返回值的尝试都会导致undefined behavior,因为无效的内存访问。

    相反,您可以将p 设为指针,使用malloc() 或family 动态分配内存,然后将该指针返回给调用者。动态分配的内存将具有等于整个程序执行的生命周期(除非手动释放),因此,即使在从函数返回后,在调用者中,返回的指针也是有效的。 p>

    【讨论】:

      【解决方案3】:

      正如我之前的人所指出的,您正在尝试返回堆栈分配的变量(函数中的局部变量),这意味着您指向的内存在函数退出后无效(它会清除一些实现,但实际上它的行为没有定义)。

      解决方案是使用malloc,如前所述,或者传递一个指向函数的指针(从而避免malloc 和free),保持调用函数的堆栈上的分配。

      即(这可能行不通,没有经过测试,只是为了演示这个想法):

      #include <stdio.h>
      #include <stdlib.h>
      
      int funcTest(float *p, int *a, int size)
      {
          int i;
          for(i=0; i< size; i++){
              p[i] = *a;
              p[i]=p[i]/2;
              a++;
          }
          for(i =0; i<size; i++){
              printf("%f\n",p[i]);
          }
          // we can use the return value for errors.
          return 0;
      }
      
      int main()
      {
          int a[4] = {1,5,3,7};
          float p[4] = {0};
          int size = 4;
          int i;
          funcTest(p, a, size);
          for(i =0; i<size; i++){
              printf("%f\n",p[i]);
          }
          return 0;
      }
      

      还要注意,您不需要使用&amp;a[0] - 数组本质上是指针,所以a 是a[0] 的内存地址,而a + 1 是a[1] 的内存地址。

      祝你好运!

      【讨论】:

      • 注意:不需要返回数组。只需直接从main 打印p。
      • @CoolGuy - 是的,你是对的。我什至没有看那部分代码......我会解决这个问题:-)
      • 另外,funcTest 不需要返回一些东西,可以是void funcTest(float *p, int *a, int size)
      • @Garf365 ,是的,这里是真的,但使用错误检查是一种很好的做法,所以我留下了一个 return 0 以向正确的方向轻推...... ;-)
      【解决方案4】:

      p 是一个自动局部变量,一旦函数返回将不再存在。返回指向它的指针将调用未定义的行为。

      动态分配p

      float *p = malloc(size*sizeof(float)); 
      

      完成后释放分配的内存

      float *k;
      k = funcTest(&a[0],size);
      if(k == NULL)             // Check for null pointer
          exit(0);
      float *temp = k;
      for(i =0; i<size; i++){
          printf("%f\n",*k);
          k++;
      }
      free(temp);              // Free allocated memory
      return 0;
      

      【讨论】:

      • @SouvikKundu 不要忘记在不再需要内存时释放它。如果忘记了,就会发生内存泄漏
      【解决方案5】:
      #include <stdio.h>
      #include <stdlib.h>
      
      void funcTest(int *a, int size, float *output)
      {
          output = (float *) malloc(sizeof(float) * size);
          int i;
          for(i=0; i< size; i++){
              output[i] = *a;
              output[i]=output[i]/2;
              a++;
          }
          for(i =0; i<size; i++){
              printf("%f\n",output[i]);
          }
      }
      
      int main()
      {
          int a[4] = {1,5,3,7};
          int size = 4;
          int i,j;
          float *k;
          funcTest(&a[0],size, k);
          for(i =0; i<size; i++){
              printf("%f\n",k);
              k++;
          }
          return 0;
      }
      

      这可能行得通。

      1. 删除 funcTest 中的本地定义 float p[size];
      2. 在 funcTest 中为 output 指针再添加一个参数 float *output。
      3. 分配内存,为 funcTest 中的 输出 指针(浮点数组大小)分配 sizeof(float) * size。
      4. 将变量p替换为参数output。
      5. 无需返回,将返回类型从float *改为void。
      6. 修复到 printf("%f\n",k); k 是一个地址。 *k 是一个指针。

      【讨论】:

        猜你喜欢
        • 2015-05-07
        • 1970-01-01
        • 2021-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-10
        • 1970-01-01
        • 2018-11-30
        相关资源
        最近更新 更多