Reputation: 3621
I am using a C++ library that requires that I pass it a 2D array. Their code example gives a statically sized array like this:
double data[][2] = {
{ 10, 20, },
{ 13, 16, },
{ 7, 30, },
{ 15, 34, },
{ 25, 4, },
};
But I need to pass run-time sized data. So I was attempting to do this:
// unsigned numBins is passed in to this function and set at run time
double** binData = new double*[numBins];
for(unsigned i=0; i < numBins; ++i) {
binData[i] = new double[2];
}
//Set the data with something like
// binData[7][0] = 10;
// binData[7][1] = 100;
//Later, diligently delete my data...
However, this fails in the library I am using. It ends of graphing some garbage numbers.
I understand that arrays are not pointers. And the library may be getting confused doing a "sizeof" somewhere.
If I am unable to change this library (it's 3rd party), how do I go about passing it dynamically sized data?
Thanks, Maddie.
Upvotes: 0
Views: 196
Reputation: 275405
Probably the API expects a pointer to the first element of what it assumes is a flattened representation of a 2D array.
So the easy approach is as follows:
template<typename T>
struct FlatVectorAs2D {
private:
size_t width;
size_t height;
std::vector<T> flat_vec;
public:
std::vector<T>& base() { return flat_vec; }
std::vector<T> const& base() const { return flat_vec; }
size_t w() const { return width; }
size_t h() const { return height; }
T* operator[]( size_t index1 ) {
return &flat_vec[index1*height];
}
T const* operator[]( size_t index1 ) const {
return &flat_vec[index1*height];
}
FlatVectorAs2D( size_t w = 1, size_t h = 1 ):width(w), height(h) {
flat_vec.resize(w*h);
}
void resize( size_t w, size_t h ) {
width = w;
height = h;
flat_vec.resize(w*h);
}
T* raw() { return flat_vec.data(); }
T const* raw() const { return flat_vec.data(); }
};
Use:
void api_function(double* d);
int main() {
size_t width = 50;
size_t height = 100;
FlatVectorAs2D<double> buffer( width, height );
buffer[0][1] = 1.0;
api_function( buffer.raw() );
}
naturally this will depend on how exactly the API works.
But if my guess is right, this will help.
Upvotes: 1
Reputation: 477060
Try this:
typedef double two_doubles[2];
int main()
{
two_doubles * p = new two_doubles[300];
// ...
delete[] p;
}
Now p
points to the first subarray of an array of 200 units of two doubles. That is, p[i]
is a double[2]
, and p[i][0]
, p[i][1]
are its member elements.
(Even better to use std::unique_ptr<two_doubles[]> p(new two_doubles[300]);
and forget about the memory management.)
Upvotes: 0