casting from void*

C

Cristiano

I have a structure like this (the actual structure is much bigger):

struct Generic {
char ID[6];
std::vector <obj1_info> info1;
std::vector <obj2_info> info2;
std::vector <obj3_info> info3;
std::vector <obj4_info> info4;
};

I use it to store 4 types of objects.
Each object needs its own std::vector to store informations related to
that object.

To avoid wasting of space I though to use a void * instead:

struct Generic {
char ID[6];
void *ptr;
};

Not a good idea, I know.
First question: does anybody have a good idea?

I allocate the right std::vector using:

ptr= new std::vector<obj1_info>;
obj1_info x; x.var= 0;
((std::vector<obj1_info>*)ptr)->push_back(x);

but when I try to read x (using some horrible casting) I get errors
(violation access, wrong result).
How should I cast the ptr pointer?

Thanks
Cristiano
 
V

Victor Bazarov

I have a structure like this (the actual structure is much bigger):

struct Generic {
char ID[6];
std::vector <obj1_info> info1;
std::vector <obj2_info> info2;
std::vector <obj3_info> info3;
std::vector <obj4_info> info4;
};

I use it to store 4 types of objects.
Each object needs its own std::vector to store informations related to
that object.

To avoid wasting of space I though to use a void * instead:

struct Generic {
char ID[6];
void *ptr;
};

Not a good idea, I know.
First question: does anybody have a good idea?

Use a union, that's what they are for.

struct Generic {
char ID[6];
union {
std::vector<obj1_info> info1;
std::vector<obj2_info> info2;
...
} u;
};

That way all of your 'infoN' objects will share the memory, and since
they can never co-exist (IOW, it's exclusive use of memory) and you can
ensure that what you put into the 'u' is what you get out (IOW, never
try to write 'u.info1' and then read 'u.info2'), you're going to be OK.
I allocate the right std::vector using:

ptr= new std::vector<obj1_info>;
obj1_info x; x.var= 0;
((std::vector<obj1_info>*)ptr)->push_back(x);

but when I try to read x (using some horrible casting) I get errors
(violation access, wrong result).
How should I cast the ptr pointer?

Don't.

With a union you will need to make sure to clear the currently allocated
vector just before you put the other one in (if ever), but that's the
only hassle.

Now, if you still don't want to use a union, I'd recommend writing
accessor methods for 'Generic'. Something like

struct Generic {
... // whatever data layout
template<class D> Generic(const D& primer) {
// set the ID somehow
std::vector<D> *pV = new std::vector<D>();
pV->push_back(primer);
ptr = pV;
}
};

and use it similarly to

obj1_info x; // and whatever else
..
Generic gen(x); // will invoke the right constructor

You will also need accessors for the elements of those vectors that will
check the ID, but for those you will need to supply the ID. Do you have
the interface in mind?

As you probably already understand, I *strongly* recommend *against*
keeping your 'Generic' type the "dumb data". Give it some intelligence
by supplying proper member functions for accessing the data. You will
thank yourself later.

Good luck!

V
 
C

Cristiano

I have a structure like this (the actual structure is much bigger):

struct Generic {
char ID[6];
std::vector <obj1_info> info1;
std::vector <obj2_info> info2;
std::vector <obj3_info> info3;
std::vector <obj4_info> info4;
};

I use it to store 4 types of objects.
Each object needs its own std::vector to store informations related to
that object.

To avoid wasting of space I though to use a void * instead:

struct Generic {
char ID[6];
void *ptr;
};

Not a good idea, I know.
First question: does anybody have a good idea?

Use a union, that's what they are for.

struct Generic {
char ID[6];
union {
std::vector<obj1_info> info1;
std::vector<obj2_info> info2;
...
} u;
};

I like that idea, but I get the compiler error that a union member
cannot have a copy ctor:
http://msdn.microsoft.com/en-us/library/bd149yt8(v=vs.80).aspx
Now, if you still don't want to use a union, I'd recommend writing
accessor methods for 'Generic'. Something like

struct Generic {
... // whatever data layout
template<class D> Generic(const D& primer) {
// set the ID somehow
std::vector<D> *pV = new std::vector<D>();
pV->push_back(primer);
ptr = pV;
}
};

and use it similarly to

obj1_info x; // and whatever else
..
Generic gen(x); // will invoke the right constructor

You will also need accessors for the elements of those vectors that will
check the ID, but for those you will need to supply the ID. Do you have
the interface in mind?

No, I'm still building the structures I need.
Instead of writing all that code, I guess it's better to waste some
memory, but I need to check what happens without the union.
As you probably already understand, I *strongly* recommend *against*
keeping your 'Generic' type the "dumb data". Give it some intelligence
by supplying proper member functions for accessing the data. You will
thank yourself later.

Good luck!

Thank you
Cristiano
 
S

s0suk3

I have a structure like this (the actual structure is much bigger):



struct Generic {

char ID[6];

std::vector <obj1_info> info1;

std::vector <obj2_info> info2;

std::vector <obj3_info> info3;

std::vector <obj4_info> info4;

};



I use it to store 4 types of objects.

Each object needs its own std::vector to store informations related to

that object.



To avoid wasting of space I though to use a void * instead:



struct Generic {

char ID[6];

void *ptr;

};



Not a good idea, I know.

First question: does anybody have a good idea?

You can create an abstract base class that's conceptually an interface and have all the info's implement it:

class ObjectInfo
{
public:
virtual Xyz GetXyz() const = 0;
virtual Zyx GetZyx() const = 0;
};

class Object1Info : public ObjectInfo { ... };
class Object2Info : public ObjectInfo { ... };

And the vector in Generic will store ObjectInfo pointers:

struct Generic
{
char ID[6];
std::vector<ObjectInfo*> info; // or maybe vector<shared_ptr<ObjectInfo>>
};

Then you can add any kind of ObjectInfo to the vector:

Object1Info* x = new Object1Info();
x->var = 0;
info.push_back(x);

Although this saves space (for the vectors), it introduces more dynamic allocations, and I'm not sure what's the space overhead of the virtual methods.
 
V

Victor Bazarov

I have a structure like this (the actual structure is much bigger):

struct Generic {
char ID[6];
std::vector <obj1_info> info1;
std::vector <obj2_info> info2;
std::vector <obj3_info> info3;
std::vector <obj4_info> info4;
};

I use it to store 4 types of objects.
Each object needs its own std::vector to store informations related to
that object.

To avoid wasting of space I though to use a void * instead:

struct Generic {
char ID[6];
void *ptr;
};

Not a good idea, I know.
First question: does anybody have a good idea?

Use a union, that's what they are for.

struct Generic {
char ID[6];
union {
std::vector<obj1_info> info1;
std::vector<obj2_info> info2;
...
} u;
};

I like that idea, but I get the compiler error that a union member
cannot have a copy ctor:
http://msdn.microsoft.com/en-us/library/bd149yt8(v=vs.80).aspx

OK, I didn't think of that. Then perhaps unions are not such a great
idea, although you could still use a union if instead of straight
vectors, you use pointers to vectors.
No, I'm still building the structures I need.
Instead of writing all that code, I guess it's better to waste some
memory, but I need to check what happens without the union.

Also, consider writing your 'Generic' actually generically (as a template):

template<class D> struct MyStuff {
char ID[6];
std::vector<D> obj_info;
};

Perhaps you need to come up with a clear interface to your class instead
of its inner workings first.

V
 
M

Melzzzzz

On 9/11/2012 7:15 AM, Cristiano wrote:
I have a structure like this (the actual structure is much
bigger):

struct Generic {
char ID[6];
std::vector <obj1_info> info1;
std::vector <obj2_info> info2;
std::vector <obj3_info> info3;
std::vector <obj4_info> info4;
};

I use it to store 4 types of objects.
Each object needs its own std::vector to store informations
related to that object.

To avoid wasting of space I though to use a void * instead:

struct Generic {
char ID[6];
void *ptr;
};

Not a good idea, I know.
First question: does anybody have a good idea?

Use a union, that's what they are for.

struct Generic {
char ID[6];
union {
std::vector<obj1_info> info1;
std::vector<obj2_info> info2;
...
} u;
};

I like that idea, but I get the compiler error that a union member
cannot have a copy ctor:
http://msdn.microsoft.com/en-us/library/bd149yt8(v=vs.80).aspx

OK, I didn't think of that. Then perhaps unions are not such a great
idea, although you could still use a union if instead of straight
vectors, you use pointers to vectors.

In c++11, I think, unions with classes that have constructors are
allowed.
 

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,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top