【问题标题】:C++ Returning Array, data loss [duplicate]C ++返回数组,数据丢失[重复]
【发布时间】:2017-09-13 16:57:12
【问题描述】:

我是来自 Java 的 C++ 新手,所以请原谅我的幼稚,但我试图将数组从函数中传递出去。我知道这样做的方法是传递一个指针,如下所示:

int *foo(){
   int arr[3] = {1, 2, 3};
   int *arrptr = arr;
   return arrptr;
}

然后访问该数组:

int main(){
   int *arrptr = foo();  //create a pointer to array

   //cout all elements
   for(int x = 0; x < 3; x++)
      cout << arrptr[x];

   return 0;
}

当然,这很好用。但是由于某种原因,在不同的代码中,这个相同的过程只返回数组的第一个值,其余的似乎是随机的。

int main(){
   stringstream allstats;
   allstats << readFile(); //readFile() simply returns a string read from a file

   while(!allstats.eof()){     //check for end of stream
      string temp;             
      getline(allstats, temp); //grab a line from allstats and put it into temp

      double *arr = calculateStats(temp); //create pointer to array of stats calculated for temp

      // print arr
      for(int x = 0; x < 6; x++)
         cout << arr[x] << endl;
      //****This spits out the correct value for arr[0] but for the rest of the array
      //****it is values like 8.58079e-306 which tells me those addresses have been
      //****overwritten.

   }
   return 0;
}

//calculate stats for each player, return as formatted string
double* calculateStats(string player){
   //cut for conciseness, just know it works and the proper values are in the following array

   //create stat array
   double statarr[6] = {(double)BA, (double)OB, (double)H, (double)BB, (double)K, (double)HBP};

   //create pointer to stat array
   double *ptr;
   ptr = statarr;

   return ptr;
}

在 Java 中,它就像返回一个数组一样简单,工作就完成了。这在 C++ 中是否可能,或者这超出了我的理解水平并且解决方案比我想象的要复杂得多?

【问题讨论】:

  • 使用 std::vector 代替数组 - 你可以从函数中返回它
  • statarr 必须是 static,如果你想这样使用的话。
  • 你为什么不直接做int *arrptr = (int*)arr?将它放入函数foo 有什么意义?顺便说一句,不同之处在于,在问题底部的函数中,您返回的是本地数组的地址,这会产生未定义的行为(该数组在该函数范围之外“不再存在”)。
  • 您的“简单”示例和您的代码非常不同。您应该使用 std::vector 而不是原始数组。
  • 实用提示:学习 C++ 的最佳方法是完全彻底忘记你对 Java 的了解。白手起家。 C++ 和 Java 的语法看似相似,但 C++ 的类、对象和内存模型与 Java 根本不同,它们几乎没有共同之处。所示代码中的错误对于来自 Java 背景的人来说是典型的错误,他们不必担心对象生命周期范围之类的事情。不幸的是,需要在 C++ 中做到 100% 正确,并充分理解自动作用域和动态作用域之间的根本区别。

标签: c++ arrays pointers


【解决方案1】:

您不能在外部函数中拥有对局部数组的指针引用,因为一旦局部函数退出,它的堆栈可能会被重用,并且局部变量中的数据将包含垃圾。

您可以将单词 static 添加到本地数组声明中,以使其内存在其他函数(和重复调用)中保持不变。虽然这根本不是推荐的解决方案。

变化:

double statarr[6] = {(double)BA, (double)OB, (double)H, (double)BB, (double)K, (double)HBP};

收件人:

static double statarr[6] = {(double)BA, (double)OB, (double)H, (double)BB, (double)K, (double)HBP};

虽然,更好的解决方案是不将数组声明为 calculateStats

类似:

    //calculate stats for each player, return as formatted string
double* calculateStats(string player, double *outArr){
   //cut for conciseness, just know it works and the proper values are in the following array

   //create stat array
   outArr[0] = (double)BA;
   outArr[1] = (double)OB;
   outArr[2] = (double)H;
   outArr[3] = (double)BB;
   outArr[4] = (double)K;
   outArr[5] = (double)HBP;


   return outArr;
}

然后有:

int main(){
   stringstream allstats;
   allstats << readFile(); //readFile() simply returns a string read from a file

   while(!allstats.eof()){     //check for end of stream
      string temp;             
      getline(allstats, temp); //grab a line from allstats and put it into temp

      double arr[6]
      calculateStats(temp, arr) //create pointer to array of stats calculated for temp

      // print arr
      for(int x = 0; x < 6; x++)
         cout << arr[x] << endl;
      //****This spits out the correct value for arr[0] but for the rest of the array
      //****it is values like 8.58079e-306 which tells me those addresses have been
      //****overwritten.

   }
   return 0;
}

【讨论】:

  • 哦!因此,无需返回新数组,只需修改现有数组地址处的数据即可!有什么理由不使用这个解决方案吗?
  • @Insederec 你也可以使用std::array,它允许从函数中返回。
  • @Insederec “有什么理由不使用这个解决方案吗?” - 好吧,只返回一个 std::vector 就简单多了。而且,static 变量会打开它们自己的全新蠕虫罐。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-03
  • 1970-01-01
  • 2013-02-16
  • 2013-01-25
相关资源
最近更新 更多