Is there is a way/trick to pass std::set to a C API which expects C Array?
            Asked
            
        
        
            Active
            
        
            Viewed 406 times
        
    3 Answers
11
            
            
        Not directly, but you can first convert the set to a vector (called, say, vec), and then pass &vec[0], which is a pointer to the first element of the internal vector array.
With C++11, you can pass vec.data() instead of &vec[0].
3
            No, but you could fill an array with your set contents pretty quickly. For example, assuming mySet is a set of the same type as YOUR_TYPENAME:
YOUR_TYPENAME arr* = new YOUR_TYPENAME[mySet.size()];
std::copy(mySet.begin(), mySet.end(), arr);
Then just pass arr into the C API.
        John Humphreys
        
- 37,047
 - 37
 - 155
 - 255
 
- 
                    4Why would you use `new` when you could use `vector`? – Mark Ransom Oct 03 '11 at 15:09
 - 
                    1+1. I like this solution more than the `vector` one, because it does not require an intermediary type. *But*, as you are dealing with a C API I'd allocate the array with `malloc` (or a derivate), especially if the array is likely to be `free`d inside the API. – Constantinius Oct 03 '11 at 15:09
 - 
                    2@Constantinius, I agree that `malloc` would be more appropriate than `new` if the ownership was passed to the API, but I wouldn't expect that to be a common case. Not sure what you mean by an intermediary type, in both cases you're creating an array of the element type. `vector` leaves you with fewer memory management issues, especially if there's any chance that an exception might be thrown somewhere. – Mark Ransom Oct 03 '11 at 15:21
 - 
                    2@Constantinius: What does "require an intermediary type" have to do with anything? Guess what: `new YOUR_TYPENAME[...]` has a type too! `std::vector` is more appropriate. The question says nothing about `free`'ing. – GManNickG Oct 03 '11 at 15:26
 - 
                    I prefer not to pass vectors into C functions even though it's really just contiguous memory either way (I've actually seen non-standard compliant vector implementations on some embedded OS's, so I don't like to rely on the vector being contiguous) - but I do agree malloc would be a better thing to use given we're working with C :) – John Humphreys Oct 03 '11 at 15:27
 - 
                    2@Constantinius, this is purely academic since we don't know the specifics of the API, but in general, if the API is going to free memory you allocate, it _must_ specify exactly how should you allocate it. `malloc` and `free` won't do much good if two CRTs happen to be used (and obviously, neither will `new` and `delete`). So in case of memory ownership transfer across API boundaries, there are no best practices - just strict definitions (given you can't change the API). – Eran Oct 03 '11 at 16:23
 
1
            
            
        For completeness, the vector alternative to the currently accepted answer would look like this:
{
  std::vector<YOUR_TYPENAME> arr(mySet.begin(), mySet.end());
  Your_C_API(&arr[0]);
  // memory implicitly freed on next line
}
I prefer this style because:
- It takes one fewer lines, and
 - It eliminates a class of mistakes that I often make (that is, forgetting to 
delete). 
        Robᵩ
        
- 163,533
 - 20
 - 239
 - 308