I am learning to use void pointers. Here I have created a resource class which can store any type of structure in (void *) and now when I try to get that structure back in (void *), I am not able to get same data back. Please help here
#include <iostream>
using namespace std;
class resource{
private:
void* data;
public:
void set(void* val){
data = val;
}
void get(void* val){
val = data;
}
};
class student{
struct st{
int id;
int age;
};
public:
void func(){
st *st1 = (st *)malloc(sizeof(st));
st1->id = 5;
st1->age = 10;
resource *rsrc = new resource();
rsrc->set((void*)st1);
void *data;
rsrc->get(&data);
st *st2 = (st*)data;
cout<<"get data %d"<<st2->id<<endl; // HERE I want to get same data back
}
};
int main() {
student *stu = new student();
stu->func();
return 0;
}
Just change the signature of get to return a void *:
void *get(){
return data;
}
And subsequently:
void *data = rsrc->get();
Also, it is idiomatic to use new, rather than malloc, to construct objects, although for POD (plain-old-data) types, either is valid.
Your get method won't return any value. You are passing a void pointer to it and inside the method, you overwrite that void pointer. However, that only overwrites the local copy of the void pointer and does not return a value. As others stated, you either have to pass a pointer to a pointer or use the return statement to return the value of the pointer.
In your specific case, #PaulSanders made the correct suggestion. You should use the getter/setter pattern. Also, he is correct that you should use new and delete in idomatic C++.
For user-created classes, most people specify classes with the first letter as a captial:
class Resource {};
class Student {};
It depends on your coding standard. It matters less whether you use camel case or not so long as you use a consistent naming convention.
Also, we generally try to prevent loss of type information in C++. Of course, you can use a C-style cast which will just reinterpret the pointer as the specified type but that is considered bad style and likely to cause problems.
Related
what is the correct approach for converting void * to pointer to struct or class.
sometime mistakes can happen like pointer to different class or struct was assigned.how to catch these types of mistakes over compile or run time.
following program tried, surprisingly it compiled and no crash even after execution.
what is right way for type casting from void * to pointer to struct or class in cpp
Description:
how to avoid type casting related issues from void * to pointer to class or struct at compile time or runtime. if static_cast is used for conversion from void * then code is compiled, even it is invalid conversion.
#include <iostream>
using namespace std;
struct stu
{
int x;
int y;
int z;
};
struct clg
{
int x;
float y;
char z;
};
void fun(void *msg)
{
clg *myclg = static_cast<clg*>(msg);
cout<<"casting is done."<<endl;
}
int main()
{
stu* st = new stu();
clg* cl = new clg();
void *ptr = st;
fun(ptr);
return 0;
}
You can't type check a void pointer. It points to a memory address but you are responsible for managing the size of the memory chunk it points to. In other words, void* doesn't give more information than : this is a memory address. Compare to a char* that holds the information : this is a memory address and from this address to the next 7 bits address, is one chunk of data. Now, that's very unsafe, but in most cases, you shouldn't find yourself using one (unless you're coding legacy c++ but given the c++14 tag, I reckon it isn't the case).
void* was used to implement generic functions in case you didn't know the type of data that was going to be used. There are essentially two solutions to get around it : heritage and templates.
There are cases when you will have to use void pointers. One of them would be when interfacing with C code as C will only take generic pointers. Another use case would be when you don't care about the data format (memcpy for exemple). But then, no type casting is needed here.
If I create a class in c++, it is possible to call a function of an object of this class, even if this class does not exists.
For example:
Class:
class ExampleClass
{
private:
double m_data;
public:
void readSomeData(double param)
{
m_data = param;
}
}
Any function where this class is used:
int main()
{
ExampleClass* myClass;
myClass->readSomeData(2.5);
}
Ofcourse this wouldn't function, because myClass is not defined.
To avoid such situations, I check if ExampleClass objects are a null_ptr
example:
void readSomeData(double param)
{
if(this == null_ptr)
return;
m_data = param;
}
But gcc says:
'this' pointer cannot be null in well-defined C++ code; comparison may
be assumed to always avaluate to false.
Ofcourse that is only a warning, but I think it is not nice to have this warning. Is there a better way to check if the pointer of a class is defined?
Testing it in the class is the wrong way, the warning is correct about that if your code is well defined then this must not be null, so the test should happen at the time when you call the member function:
int main()
{
ExampleClass* myClass = nullptr; // always initialize a raw pointer to ensure
// that it does not point to a random address
// ....
if (myClass != nullptr) {
myClass->readSomeData(2.5);
}
return 0;
}
If a pointer must not be null at a certain part of your code then you should do it according to CppCoreGuideline: I.12: Declare a pointer that must not be null as not_null
Micorosoft provides an Guidelines Support Library that has an implementation for not_null.
Or if possible then don't use pointers at all but std::optional.
So a code setup could look like this:
#include <gsl/gsl>
struct ExampleClass {
void readSomeData(double ){}
};
// now it is clear that myClass must not and can not be null within work_with_class
// it still could hold an invalid pointe, but thats another problem
void work_with_class(gsl::not_null<ExampleClass*> myClass) {
myClass->readSomeData(2.5);
}
int main()
{
ExampleClass* myClass = nullptr; // always initialize a raw pointer to ensure
// that it does not point to a random address
// ....
work_with_class(myClass);
return 0;
}
The best way is not use pointers at all:
int main()
{
ExampleClass myClass;
myClass.readSomeData(2.5);
}
That way there's no need for any check, and in fact, checking this inside the function is moot.
If you need nullability, use std::optional instead.
Either don't use pointers as Bartek Banachewicz has pointed out, or properly initialize and check the pointer:
int main()
{
ExampleClass* myClass= 0;
if (myClass)
myClass->readSomeData(2.5);
return 0;
}
Of course you still have to add the instantiation of the object at some point, otherwise the code is nonsense.
Guys I have a function like this (this is given and should not be modified).
void readData(int &ID, void*&data, bool &mybool) {
if(mybool)
{
std::string a = "bla";
std::string* ptrToString = &a;
data = ptrToString;
}
else
{
int b = 9;
int* ptrToint = &b;
data = ptrToint;
}
}
So I want to use this function in a loop and save the returned function parameters in a vector (for each iteration).
To do so, I wrote the following struct:
template<typename T>
struct dataStruct {
int id;
T** data; //I first has void** data, but would not be better to
// have the type? instead of converting myData back
// to void* ?
bool mybool;
};
my main.cpp then look like this:
int main()
{
void* myData = nullptr;
std::vector<dataStruct> vec; // this line also doesn't compile. it need the typename
bool bb = false;
for(int id = 1 ; id < 5; id++) {
if (id%2) { bb = true; }
readData(id, myData, bb); //after this line myData point to a string
vec.push_back(id, &myData<?>); //how can I set the template param to be the type myData point to?
}
}
Or is there a better way to do that without template? I used c++11 (I can't use c++14)
The function that you say cannot be modified, i.e. readData() is the one that should alert you!
It causes Undefined Behavior, since the pointers are set to local variables, which means that when the function terminates, then these pointers will be dangling pointers.
Let us leave aside the shenanigans of the readData function for now under the assumption that it was just for the sake of the example (and does not produce UB in your real use case).
You cannot directly store values with different (static) types in a std::vector. Notably, dataStruct<int> and dataStruct<std::string> are completely unrelated types, you cannot store them in the same vector as-is.
Your problem boils down to "I have data that is given to me in a type-unsafe manner and want to eventually get type-safe access to it". The solution to this is to create a data structure that your type-unsafe data is parsed into. For example, it seems that you inteded for your example data to have structure in the sense that there are pairs of int and std::string (note that your id%2 is not doing that because the else is missing and the bool is never set to false again, but I guess you wanted it to alternate).
So let's turn that bunch of void* into structured data:
std::pair<int, std::string> readPair(int pairIndex)
{
void* ptr;
std::pair<int, std::string> ret;
// Copying data here.
readData(2 * pairIndex + 1, ptr, false);
ret.first = *reinterpret_cast<int*>(ptr);
readData(2 * pairIndex + 2, ptr, true);
ret.second = *reinterpret_cast<std::string*>(ptr);
}
void main()
{
std::vector<std::pair<int, std::string>> parsedData;
parsedData.push_back(readPair(0));
parsedData.push_back(readPair(1));
}
Demo
(I removed the references from the readData() signature for brevity - you get the same effect by storing the temporary expressions in variables.)
Generally speaking: Whatever relation between id and the expected data type is should just be turned into the data structure - otherwise you can only reason about the type of your data entries when you know both the current ID and this relation, which is exactly something you should encapsulate in a data structure.
Your readData isn't a useful function. Any attempt at using what it produces gives undefined behavior.
Yes, it's possible to do roughly what you're asking for without a template. To do it meaningfully, you have a couple of choices. The "old school" way would be to store the data in a tagged union:
struct tagged_data {
enum { T_INT, T_STR } tag;
union {
int x;
char *y;
} data;
};
This lets you store either a string or an int, and you set the tag to tell you which one a particular tagged_data item contains. Then (crucially) when you store a string into it, you dynamically allocate the data it points at, so it will remain valid until you explicitly free the data.
Unfortunately, (at least if memory serves) C++11 doesn't support storing non-POD types in a union, so if you went this route, you'd have to use a char * as above, not an actual std::string.
One way to remove (most of) those limitations is to use an inheritance-based model:
class Data {
public:
virtual ~Data() { }
};
class StringData : public Data {
std::string content;
public:
StringData(std::string const &init) : content(init) {}
};
class IntData : public Data {
int content;
public:
IntData(std::string const &init) : content(init) {}
};
This is somewhat incomplete, but I think probably enough to give the general idea--you'd have an array (or vector) of pointers to the base class. To insert data, you'd create a StringData or IntData object (allocating it dynamically) and then store its address into the collection of Data *. When you need to get one back, you use dynamic_cast (among other things) to figure out which one it started as, and get back to that type safely. All somewhat ugly, but it does work.
Even with C++11, you can use a template-based solution. For example, Boost::variant, can do this job quite nicely. This will provide an overloaded constructor and value semantics, so you could do something like:
boost::variant<int, std::string> some_object("input string");
In other words, it's pretty what you'd get if you spent the time and effort necessary to finish the inheritance-based code outlined above--except that it's dramatically cleaner, since it gets rid of the requirement to store a pointer to the base class, use dynamic_cast to retrieve an object of the correct type, and so on. In short, it's the right solution to the problem (until/unless you can upgrade to a newer compiler, and use std::variant instead).
Apart from the problem in given code described in comments/replies.
I am trying to answer your question
vec.push_back(id, &myData<?>); //how can I set the template param to be the type myData point to?
Before that you need to modify vec definition as following
vector<dataStruct<void>> vec;
Now you can simple push element in vector
vec.push_back({id, &mydata, bb});
i have tried to modify your code so that it can work
#include<iostream>
#include<vector>
using namespace std;
template<typename T>
struct dataStruct
{
int id;
T** data;
bool mybool;
};
void readData(int &ID, void*& data, bool& mybool)
{
if (mybool)
{
data = new string("bla");
}
else
{
int b = 0;
data = &b;
}
}
int main ()
{
void* mydata = nullptr;
vector<dataStruct<void>> vec;
bool bb = false;
for (int id = 0; id < 5; id++)
{
if (id%2) bb = true;
readData(id, mydata, bb);
vec.push_back({id, &mydata, bb});
}
}
I need to pass something like a pointer that takes anything as a function parameter. You know, something without any predefined type or a type that can take anything like this:
void MyFunc( *pointer );
And then use it like:
char * x = "YAY!";
MyFunc(x);
int y = 10;
MyFunc(&y);
MyObj *b = new MyObj();
MyFunc(b);
And I don't want to use templates because I am mostly using C in my project.
Is there anything that can be used here except a function macro?
In C++, Boost.Any will let you do this in a type-safe way:
void func(boost::any const &x)
{
// any_cast a reference and it
// will throw if x is not an int.
int i = any_cast<int>(x);
// any_cast a pointer and it will
// return a null pointer if x is not an int.
int const *p = any_cast<int>(&x);
}
// pass in whatever you want.
func(123);
func("123");
In C, you would use a void pointer:
void func(void const *x)
{
// it's up to you to ensure x points to an int. if
// it's not, it might crash or it might silently appear
// to work. nothing is checked for you!
int i = *(int const*)x;
}
// pass in whatever you want.
int i = 123;
func(&i);
func("123");
You seem adverse to it but I'll recommend it anyway: if you're using C++, embrace it. Don't be afraid of templates. Things like Boost.Any and void pointers have a place in C++, but it is very small.
Update:
Well , I am making a small signals - slots - connections library to be
used with my gui toolkit. So that I can get rid of the Ugly WNDPROC. I
need these pointers for the connections.
If you need multi-target signals, Boost.Signals already provides a full and tested signals/slots implementation. You can use Boost.Bind (or std::bind, if you've got a C++0x compiler) to connect member functions:
struct button
{
boost::signal<void(button&)> on_click;
}
struct my_window
{
button b;
my_window()
{
b.on_click.connect(std::bind(&my_window::handle_click,
this, std::placeholders::_1));
}
void handle_click(button &b)
{
}
void simulate_click()
{
b.on_click(b);
}
};
If you only want a simple callback, Boost.Function (or std::function if you've got a C++0x compiler) will work well:
struct button
{
std::function<void(button&)> on_click;
}
struct my_window
{
button b;
my_window()
{
b.on_click = std::bind(&my_window::handle_click,
this, std::placeholders::_1);
}
void handle_click(button &b)
{
}
void simulate_click()
{
b.on_click(b);
}
};
You can use a function that takes a void*, but you must be aware of the pointer types that are not compatible with void*:
pointers to functions:
void MyFunc(void*);
MyFunc(&MyFunc); // WRONG
pointers to members:
void MyFunc(void*);
struct A { int x; };
MyFunc(&A::x); // WRONG
While these pointers are not compatible with void* (even with casting, on some compilers), they are themselves data. So you can pass a pointer to the pointer:
void MyFunc(void*);
void (*pfn)(void*) = &MyFunc;
MyFunc(&pfn); // ok
struct A { int x; };
int A::*px = &A::x;
MyFunc(&px); // ok
You can define the method as taking one void * argument. Of course, at that point, it's up to you to figure out what to do with the data (as far as accessing it or casting it.)
void MyFunc(void * ptr);
You could use:
void MyFunc( void* p){}
int g = 10;
MyFunc( (void*)&g );
void * is the way to do it. You can assign any pointer type to and from a void *. But to use the pointer in the called function, you'll have to know the type so you can create an appropriate local pointer or cast appropriately. You can encode a limited set of types as enum symbols, and perhaps use a switch to select type-specific behavior. But without a specific purpose or use-case, you might end up chasing your tail in a quest for generality for which C was never intended.
Another way would be to make a union to contain all the various types you know are needed.
typedef union {
int i;
char c;
float f;
} vartype;
Then if the value can carry around its own type-identifier, it becomes a tag-union or variant-record.
typedef struct {
enum type { INT, CHAR, FLOAT } type;
vartype var;
} varrec;
It sounds weird, I guess, but I'm creating some low-level code for a hardware device. Dependend on specific conditions I need to allocate more space than the actual struct needs, store informations there and pass the address of the object itself to the caller.
When the user is deallocating such an object, I need to read these informations before I actually deallocate the object.
At the moment, I'm using simple pointer operations to get the addresses (either of the class or the extra space). However, I tought it would be more understandable if I do the pointer arithmetics in member functions of an internal (!) type. The allocator, which is dealing with the addresses, is the only one who know's about this internal type. In other words, the type which is returned to the user is a different one.
The following example show's what I mean:
struct foo
{
int& get_x() { return reinterpret_cast<int*>(this)[-2]; }
int& get_y() { return reinterpret_cast<int*>(this)[-1]; }
// actual members of foo
enum { size = sizeof(int) * 2 };
};
int main()
{
char* p = new char[sizeof(foo) + foo::size];
foo* bar = reinterpret_cast<foo*>(p + foo::size);
bar->get_x() = 1;
bar->get_y() = 2;
std::cout << bar->get_x() << ", " << bar->get_y() << std::endl;
delete p;
return 0;
}
Is it arguable to do it in that way?
It seems needlessly complex to do it this way. If I were to implement something like this, I would take a simpler approach:
#pragma pack(push, 1)
struct A
{
int x, y;
};
struct B
{
int z;
};
#pragma pack(pop)
// allocate space for A and B:
unsigned char* data = new char[sizeof(A) + sizeof(B)];
A* a = reinterpret_cast<A*>(data);
B* b = reinterpret_cast<B*>(a + 1);
a->x = 0;
a->y = 1;
b->z = 2;
// When deallocating:
unsigned char* address = reinterpret_cast<unsigned char*>(a);
delete [] address;
This implementation is subtly different, but much easier (in my opinion) to understand, and doesn't rely on intimate knowledge of what is or is not present. If all instances of the pointers are allocated as unsigned char and deleted as such, the user doesn't need to keep track of specific memory addresses aside from the first address in the block.
The very straightforward idea: wrap your extra logic in a factory which will create objects for you and delete them smart way.
You can also create the struct as a much larger object, and use a factory function to return an instance of the struct, but cast to a much smaller object that would basically act as the object's handle. For instance:
struct foo_handle {};
struct foo
{
int a;
int b;
int c;
int d;
int& get_a() { return a; }
int& get_b() { return b; }
//...more member methods
//static factory functions to create and delete objects
static foo_handle* create_obj() { return new foo(); }
static void delete_obj(foo_handle* obj) { delete reinterpret_cast<foo*>(obj); }
};
void another_function(foo_handle* masked_obj)
{
foo* ptr = reinterpret_cast<foo*>(masked_obj);
//... do something with ptr
}
int main()
{
foo_handle* handle = foo::create_obj();
another_function(handle);
foo::delete_obj(handle);
return 0;
}
Now you can hide any extra space you may need in your foo struct, and to the user of your factory functions, the actual value of the pointer doesn't matter since they are mainly working with an opaque handle to the object.
It seems your question is a candidate for the popular struct hack.
Is the "struct hack" technically undefined behavior?