简体   繁体   中英

How to Pass Pointer by Reference in C++

If a subroutine allocates a new buffer, how can the caller of that function pass a pointer to get the address?

Every declaration combination I've tried doesn't work, ie after calling the subroutine, the pointer passed does not get set to the address of the buffer created in the subroutine.

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;
}

Use a double level pointer?

float **fBuffer would work just fine.

This is usually done by passing a double pointer, or the real C++ way is to use std::unique_ptr or std::vector :

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;
}

double pointer:

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...
   }
}

And as Konrad Rudolph said, a reference to pointer is possible too:

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];
}

Note that you can also pass in references to vectors or unique_ptrs, eg:

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

Your code actually works as-is (apart from the fact that you need to declare readFloatData before using it). The question is whether this is really a good idea – why not return the new value instead? This is what return values are for, after all:

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;
}

That said, raw pointers shouldn't own memory anyway. Use a std::unique_ptr or similar instead. For arrays, use std::vector<float> instead of a pointer-to-array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM