Sign in to follow this  
31337noob

void * help

Recommended Posts

31337noob    101
sorry to bug you guys again but i am stuck again. i have a vector<void *>data now that vector holds the following bool,int,float,D3DXCOLOR,D3DXVECTOR3,string. now i am having problems with the data not being the same. example
void *m_data;
m_data = new bool;
fscanf(afile,"%s",buffer);
bool b;
if(strcmp(buffer,"true")==0)
{
   b = true;
}
else
{
   b = false;
}
memcpy(m_data,&b,sizeof(bool));
data.push_back(m_data);
bool a = (bool)&m_data;
if(a==b)
 MessageBox(0,0,0,0);
delete m_data;


it never does the messagebox because the data is not the same. why?

Share this post


Link to post
Share on other sites
Clash    342
bool a = (bool*)m_data;

is the same as

bool a = (m_data != 0);

In other words, you're casting void* to bool* and then setting a bool to it. Unless that is a null pointer, your value is going to be true. And true is usually 1, which is not what m_data was. What you really want is

bool a = *reinterpret_cast<bool*>(m_data);

Also, don't do this. Use polymorphism to achieve whatever you're trying to do. Void* is almost always evil.

Good luck.

Share this post


Link to post
Share on other sites
My first thought is "Why are you trying to do that?" because I have never seen an actual need for that.

My second thought is "Please, please, please use boost::any"

The biggest problem was sortof mentioned, but it looks like different source then quoted. In your source you have:
bool a = (bool)&m_data;

but:
m_data is a void*.
&m_data is a void**
(bool)&m_data is a boolean which will always be true because &m_data points to a stack variable (which points to a heap variable which may be true or false).
a is then always set to true.

What you're supposed to do is:
bool a = *(bool*)m_data;

Or use reinterprit_cast<bool*> instead of (bool*).

If it's not working, you didn't copy it right. It's "dereferance m_data as if it were a pointer to a boolean", *(bool*)m_data. Notice the two asterisks, and NO ampersands.

Share this post


Link to post
Share on other sites
demonkoryu    980
Why do you want to do that? I mean, how are you going to distinguish what is what later on and what are you trying to achieve? Maybe we can find a cleaner solution or there is a handy boost lib you can use.

edit: Beaten by erzengeldeslichtes [eviltonque]

Share this post


Link to post
Share on other sites
Roboguy    794
Quote:
Original post by 31337noob
store different type of values in a vector

like bool,int,float,D3DXVECTOR3,D3DXCOLOR,string


I know. I meant why are you trying to do that.

Share this post


Link to post
Share on other sites
fearyourself    122
Changing a bit of the program so that it isn't too Windowsy (I'm under linux)... If you really wanted void* elements, then this would be better...

I admit I'm more a C programmer than a C++ one, so you C++ purist, don't look, you'll crisp and probably have a hard attack...

That said, I agree with everybody in saying that void* elements should be used with great care, you better know what you are doing...


#include <stdlib.h>
#include <iostream>
using namespace std;

int main(int argc, char **argv)
{
void *m_data;
m_data = new bool;

bool b;

//Just to easily test true or false without recompiling
b = argc>1;

memcpy(m_data,&b,sizeof(bool));

//This becomes slightly ugly but once you think about it, it should be logical
bool a = *((bool *) m_data);

//This should always (and does) do the if and not the else
if(a==b)
cout << "A==B\n";
else
cout << "A!=B\n";

//Clear up the new, again, C++ purists will hate me for this one
delete ((bool*) m_data);

return 1;
}




It sometimes happens (I suppose) that you may need a vector that can hold different types and generally a void* seems the easy solution. But I think you are stretching it a bit... What kind of element in your program could be a bool,int,float,D3DXCOLOR,D3DXVECTOR3,string?

If you rethink your problem, you'll probably get a better solution that will not need a void* vector, seeing as you are having problems with it...

To end this post will be a:

I'm sorry I have posted an example with void*
I'm sorry I actually like void*
I promise not to say it again, lol

Jc

Share this post


Link to post
Share on other sites
MTclip    242
just another example


#include <iostream>
#include <vector>

using namespace std;

void main()
{
vector<void*> voidVec;

int i = 5;
float f = 7.7;
double d = 5.5;
char c = 'p';

voidVec.push_back(&i);
voidVec.push_back(&f);
voidVec.push_back(&d);
voidVec.push_back(&c);

cout << *(int*)voidVec[0] << endl;
cout << *(float*)voidVec[1] << endl;
cout << *(double*)voidVec[2] << endl;
cout << *(char*)voidVec[3] << endl;

system("pause");
}





Share this post


Link to post
Share on other sites
Roboguy    794
Quote:
Original post by 31337noob
i am tring to make a script system
that holds the data.


Then you should use something like Boost.Variant or Boost.Any (www.boost.org). You need to be able to find the type of the data later so you can decide how to deal with it (you will probably also want to use something like std::map, since you probably want to bind the values to variables).

Share this post


Link to post
Share on other sites
snk_kid    1312
Quote:
Original post by 31337noob
i am tring to make a script system
that holds the data.


Even if you where doing this in pure C there is a better solution to void pointers since you are only dealing with a small set of types you could have used a tagged union to simulate variant types. In C++ use boost::variant:


#include <algorithm> // for_each
#include <vector>
#include <string>
#include <iostream>
#include <boost/variant.hpp>
#include <d3dx9.h>

typedef boost::variant<bool, int, float, D3DXCOLOR, D3DXVECTOR3, std::string> script_vari;

struct type_printer : boost::static_visitor<> {
template < typename Tp >
void operator()(const Tp&) const {
std::cout << "type is: " << typeid(Tp).name() << '\n';
}
};

int main() {

std::vector<script_vari> varis;

varis.push_back(true);
varis.push_back(10);
varis.push_back(10.03f);
varis.push_back(std::string("foo"));
varis.push_back(D3DXCOLOR(1.0f, 1.0f, 0.0f, 1.0f));
varis.push_back(D3DXVECTOR3(1.0f, 1.0f, 1.0f));

std::for_each(varis.begin(), varis.end(),
boost::apply_visitor(type_printer()));
}


Take note that variant's can be recursive aswell no need to abuse OO here.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this