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