【问题标题】:How to Pass Pointer by Reference in C++如何在 C++ 中通过引用传递指针
【发布时间】:2015-01-17 21:43:18
【问题描述】:

如果子程序分配了一个新的缓冲区,该函数的调用者如何传递一个指针来获取地址?

我尝试过的每个声明组合都不起作用,即在调用子例程后,传递的指针没有设置为在子例程中创建的缓冲区的地址。

int main ()
{
   float *fMyBuffer;

   // Pointer Update
   readFloatData ( fMyBuffer ); // &fMyBuffer  *fMyBuffer 

   // Deallocate Memory
   delete [] fMyBuffer;
}


void readFloatData(float *&fBuffer)  //*fBuffer   &fBuffer
{
  // Create New Buffer
  float *fData;
  fData = new float [1000];

  // Pass our buffer Address to user's pointer
  fBuffer = fData;
}

【问题讨论】:

  • 如果对float 的引用是float*,那么对float * 的引用是?
  • @Sjuan 通常是个非常糟糕的主意? :-)
  • 非常简单:1)函数签名:void readFloatData(float **fBuffer) {...},2)函数调用:readFloatData (&fMyBuffer );,3)删除“readFloatData():”中的所有(现在无关的)内容。
  • 我唯一能看出你发布的代码有问题的是你在声明之前调用了一个函数。
  • 谢谢,应该提到,为了清楚起见,我省略了一些细节,比如函数原型声明部分。此外,虽然函数通常返回句柄,但我的实际函数需要返回 2 个指针地址,所以这就是我想将其作为参数的原因。虽然,我敢打赌有一种方法可以返回多个指针(使用向量/unique_ptrs),但是我对这些类型不是很熟悉。

标签: c++ pointers reference pass-by-reference


【解决方案1】:

这通常通过传递一个双指针来完成,或者真正的C++方式是使用std::unique_ptrstd::vector

矢量:

int main(int argc, char** argv)
{
   std::vector<float> fMyBuffer = readFloatData ();
   return 0;
}


std::vector<float> readFloatData()
{
  // Create New Buffer
  std::vector<float> fData(1000);

  // Populate vector...

  return fData;
}

unique_ptr:

int main(int argc, char** argv)
{
   std::unique_ptr<float[]> fMyBuffer = readFloatData (); // Note the [] is MUST else the wrong deleter will be used
   return 0;
}


std::unique_ptr<float[]> readFloatData()
{
  // Create New Buffer
  std::unique_ptr<float[]> fData(new float[1000]);

  // Populate data...

  return fData;
}

双指针:

int main(int argc, char** argv)
{
   float* fMyBuffer = nullptr;
   readFloatData(&fMyBuffer);
   delete[] fMyBuffer;
   return 0;
}


void readFloatData(float** fData)
{
  if (fData)
  {
      // Create New Buffer
      *fData = new float[1000];

     // Populate data...
   }
}

正如 Konrad Rudolph 所说,对指针的引用也是可能的:

int main(int argc, char** argv)
{
   float* fMyBuffer = nullptr;
   readFloatData(fMyBuffer);
   delete[] fMyBuffer;
   return 0;
}


void readFloatData(float*& fData)
{
   // Create New Buffer
   fData = new float[1000];
}

请注意,您也可以传入对向量或 unique_ptrs 的引用,例如:

void readFloatData(std::unique_ptr<float[]>& fData)
void readFloatData(std::vector<float>& fData)

【讨论】:

  • 您还可以传递对原始指针的引用,这是您的答案未提及的事情。因此也不需要双指针。
  • 是的,我想我也会添加的
  • 对指针示例的引用是我想到的,没有显式赋值的事实更酷!正如一些人指出的那样,原始代码应该可以工作,但我在解释寻址时犯了错误。调试器显示 fData @0x28fe24: 0x3d6f460 我认为缓冲区位于 0x28fe24 ......然后当函数返回我的fMyBuffer 指针设置为 0x3d6f460,而不是 0x28Fe24。
【解决方案2】:

使用双级指针?

float **fBuffer 可以正常工作。

【讨论】:

  • 你可以这样做,但你不需要。
  • 使用双指针是不好的建议,因为它不是真正地道的 C++
【解决方案3】:

Your code actually works as-is(除了你需要在使用之前声明readFloatData)。问题是这是否真的是一个好主意——为什么不返回新值呢?毕竟,这就是返回值的用途:

float* readFloatData()
{
  // Create New Buffer
  float *fData = new float [1000];

  // Pass our buffer Address to user's pointer
  return fData;
}

int main() {
  float* fMyBuffer = readFloatData();
  // …
  delete [] fMyBuffer;
}

也就是说,原始指针无论如何都不应该拥有内存。请改用std::unique_ptr 或类似名称。对于数组,使用std::vector&lt;float&gt; 而不是指向数组的指针。

【讨论】:

  • 这不是“原样”,确切地说。您移动了一些东西,这可能是最初的问题。
  • @Ben Fair 点,我已经修改了。也就是说,OP 的描述绝对听起来像是编译后的代码,只是做了一些意想不到的事情。所以我很确定这不是最初的问题。
猜你喜欢
  • 2020-03-14
  • 2012-03-03
  • 1970-01-01
  • 1970-01-01
  • 2011-04-06
  • 1970-01-01
  • 2010-12-04
  • 2014-09-11
  • 1970-01-01
相关资源
最近更新 更多