3

I am using LAPACK library to create a R-package using C++. I am using unique_ptr for defining the arrays as

   unique_ptr<double[]> my_arr(new double[arr_length]);

I then pass this unique_ptr to library function (FORTRAN function) which accepts pointer to double array and will update this array inside the function as

   F77_CALL(daxpy) (&num_feat_, &beta, tmp, &inc_one, my_arr.get(), &inc_one);

After going through web, I noticed it is not recommended to pass unique_ptr as pointer argument to a function. However, the library functions I am using needs a pointer in their argument. I can not release the pointer before sending it to the function since the library function needs to update the pointer. Is there any efficient way to handle this?

T.C.
  • 133,968
  • 17
  • 288
  • 421
  • 4
    Obviously it's a bit of an uncomfortable thing to do, since you're explicitly sidestepping all of the mechanisms that make a unique_ptr safe; but in a similar question [here](http://stackoverflow.com/questions/9908535/unique-ptr-with-an-api-that-expects-raw-pointers), the consensus seemed to be that when dealing with an API that expects raw pointers (Fortran, C, or whatever) that using .get() is ok when the routines aren't going to be doing any memory management with the pointer (which BLAS certainly won't). Note to that DAXPY won't update the _pointer_; it updates the data pointed to. – Jonathan Dursi Sep 15 '14 at 18:09
  • @JonathanDursi I don't think it is an uncomfortable thing to do. I think it is a perfectly natural thing to do. The calling code has unique ownership of the array and you *know* it will be alive for the duration of the call to the library. I think this is the right way to call functions even if they are in your own code. This is assuming the function is not trying to take ownership of the array and call delete on it later in which case using unique_ptr is a bad idea. – Chris Drew Nov 18 '14 at 08:59

1 Answers1

0

Assuming the library is not going to take ownership of the array and try to delete it itself I think this is perfectly fine.

You should generally prefer to pass by reference or raw-pointer and normally only pass unique_ptr when you are transferring ownership so I think this is correct. The calling code retains unique ownership of the array.

You know the array will not be deleted until after the function call when the unique_ptr goes out-of-scope which is exactly what you want.

I think this is the right way of calling functions that are not going to take ownership even if they are in your own code.

See GotW #91 for a summary on how to pass (smart) pointers.

If the library retained the pointer after the function call you would have to ensure the unique_ptr did not go out-of-scope before the library finished using it which is a little more tricky.

There are some libraries that assume you will allocate objects on the heap and give them ownership via a raw pointer (I've seen it in some visualization libraries). They delete the object when they are done. This is generally considered bad practice in C++11 but if you need to call such libraries you should not use a unique_ptr as you don't want to delete the object yourself.

Chris Drew
  • 14,926
  • 3
  • 34
  • 54
  • Why wouldn't you pass `unique_ptr` as an argument? For me it like a Fortran's `allocatable` and there is no problem passing it around. When the functions returns, you get the current state of the variable. – Vladimir F Героям слава Nov 18 '14 at 10:21
  • @VladimirF There are some cases where you want to pass a `unique_ptr` the most common is to transfer ownership which I mentioned. [GotW #91](http://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters/) gives a good summary. But in most cases (like this one) you are not transferring ownership and you should use a raw-pointer or reference instead. Unless you are reseating the pointer (which might be what you are referring to) there is no reason to pass a `unique_ptr` by reference. Personally, I rarely find I need to reseat a `unique_ptr` and can normally return by value instead. – Chris Drew Nov 18 '14 at 13:10