difference of POD struct array and flat array

P

Peter Steiner

hi there!

my problem: i need arrays of float-triples (math vector). i need these
available in a flat float* array for batch processing (opengl). is an
array of POD structs with three float members each equivalent to a flat
array of floats in terms of memory layout?

ie. is the following code legal?


struct Vector {
float v[3];
};

Vector vectors[3];
float flatVectors[3][3];

memcpy((const void*)flatVectors, (void*)vectors, sizeof(float)*9);
// vectors now contains the same values in Vector::v as flatVectors


i suspect that struct member alignment, as applied by compilers,
forbids that kind of usage. is that true, and if so, is there a way to
circumvent that problem in a portable fashion?

i am interested in such a solution because i would like to implement a
convenient math vector class in a platform-independend, purely object
oriented program.

-- peter
 
V

Valentin.Samko

struct Vector {
float v[3];
};

Vector vectors[3];
float flatVectors[3][3];

memcpy((const void*)flatVectors, (void*)vectors, sizeof(float)*9);
i suspect that struct member alignment, as applied by compilers,
forbids that kind of usage.
Yes. sizeof(Vector) does not have to be equal to sizeof(float)*3.
is that true, and if so, is there a way to
circumvent that problem in a portable fashion?

Write a wrapper around the raw float array. Something like

template<class T, size_t vector_size>
class Matrix
{
typedef std::vector<T> container;

template<class U, class SizeType, class Iterator>
struct VectorT
{
typedef SizeType size_type;
typedef U value_type;
VectorT() {}
value_type& operator[] (size_type pos) const { return * (ptr_ + pos);
}
private:
VectorT(const VectorT&);
VectorT& operator=(const VectorT&);
VectorT(Iterator ptr) : ptr_(ptr) {}
friend class Matrix;
Iterator ptr_;
};
public:

typedef typename container::size_type size_type;
typedef VectorT<T, size_type, typename container::iterator>
vector_proxy;
typedef VectorT<const T, size_type, typename
container::const_iterator> const_vector_proxy;

vector_proxy operator[](size_t pos) { return vector_proxy(c_.begin() +
(vector_size * pos)); }
const_vector_proxy operator[](size_t pos) const { return
const_vector_proxy(c_.begin() + (vector_size * pos)); }

T* get_raw_data_for_opengl() { return &c_[0]; }

private:
container c_;
};

Or you could even implement a full blown STL compatible matrix like
container with iterators.
 
P

Peter Steiner

thanks for the elegant solution!

i'll go for this approach, which gives me the comfort with the proxy
class and the safety by wrapping the container of raw values. win-win.
:)

-- peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top