I have an api call which populates an array of raw pointers to be used by the caller. This function heap allocates each raw pointer but does not allocate the array.
I cannot change this API function regardless of how bad it is.
Calling the api function code looks something like this:
size_t response_count = api.getResponseCount();
std::vector<Response*> responses(response_count);
api.getResponses(responses.data());
for(auto response : responses) {
// Do some processing with response
delete response;
}
I would like to wrap each response in a unique_ptr such that it is still cleaned up at the end of the loop iteration without having to explicitly call delete. Ideally, this would look something like:
for(std::unique_ptr<Response> response : responses) {
// Do some processing with response
// No need to delete response, it will be cleaned up as it goes out of scope
}
This does not compile because the compiler cannot convert a pointer to a unique_ptr:
error: conversion from ‘Response*’ to non-scalar type ‘std::unique_ptr<Response>’ requested
Is there way to cast each element of the container to a smart pointer in this way, or do I need to explicitly delete the raw pointer?
Instead of wrapping each pointer in a unique_ptr, I'd consider using a Boost ptr_vector.
Assuming the data is allocated so you actually can use delete to delete it, the code would look something like this:
size_t response_count = api.getResponseCount();
// Unfortunately, we have to define, then resize. It has a ctor that takes a size,
// but it treats that as an amount to reserve rather than an actual size.
boost::ptr_vector<Response> responses;
responses.resize(response_count);
api.getResponses(responses.c_array());
for(auto response : responses) {
// Do some processing with response
}
...and when responses goes out of scope, it will delete all the objects pointed to by the pointers it contains. If necessary, you can specify an Allocator class that defines how the objects are allocated and deleted.
Reference
https://www.boost.org/doc/libs/1_71_0/libs/ptr_container/doc/ptr_container.html
Though not considered good practice, you can derive from unique_ptr with a non explicit constructor.
template<typename P>
struct MakeUnique : std::unique_ptr<P> {
MakeUnique(P* p) : std::unique_ptr<P>(p) {}
};
This can then be used like this:
for ( MakeUnique<Response> resp : responses ) {
...
}
Probably the closest thing to a one-liner. See working version here.
You can create a wrapper for the vector<response*> that hands out unique pointers
struct wrapper{
struct iterator {
iterator( std::vector<response*>::iterator it ) : it_(it){}
friend bool operator!=( iterator const& lhs, iterator const &rhs ){ return lhs.it_ != rhs.it_; }
void operator++(){ ++it_;}
std::unique_ptr<response> operator*(){ return std::unique_ptr<response>(*it_); }
private:
std::vector<response*>::iterator it_;
};
wrapper( std::vector<response*>& rs ) : rs_{rs} {}
iterator begin() const { return iterator{rs_.begin()}; }
iterator end() const { return iterator{rs_.end()}; }
private:
std::vector<response*>& rs_;
};
You can then iterate over the responses like this:
for( auto resp : wrapper( responses ) ){...
}
See working version here.
Related
As part of a "message"-class I try to transfer pointers of different types by casting them to void*-pointers and saving them in a wrapper class ("MsgData") that remembers the original type of the pointer.
For example a bool pointer:
bool* data = new bool;
event.wheel.y < 0 ? *data = false : *data = true;
send("all", this, MSG_MOUSE_SCROLL, MsgData(data));
The compatible Constructor of MsgData is called and the variable is saved as a member of my message class:
MsgData(): type_(NULLPTR), data_(nullptr) {} // Null
MsgData(const bool* data): type_(BOOL), data_((void*)data) {} // Bool
MsgData(const std::string* data): type_(STRING_STD), data_((void*)data) {} // std::string
// ... etc.
I can cast the pointers back and use them without any errors but when I try to delete them the program crashes:
~MsgData() {
switch (type_) {
case (BOOL):
if ((bool*)data_)
delete (bool*)data_;
break;
// ... etc.
}
}
The bool pointer is just an example and the same happens with all other types and classes too.
The program crashes only when I try to delete the pointer. Casting them back to their original type and using them is not a problem.
I researched the problem and found similar question like this one on StackOverflow but while it seems to be considered bad style to cast a pointer to void* and back I cannot find the reason why the program crashes.
Well, a better solution to the problem is to use boost::variant (or std::variant). Once you start using that, all the headache of deleting and managing type and data will go automatically. You're not the first to face of a problem of this kind; many others have faced it, and the solution is available in the form of boost::variant or std::variant.
Anyway, since you're developing a solution yourself, here is my advise: construct an appropriate deleter in the constructor itself .. or whenever you know what type of data your class is going to hold:
MsgData()
: type_(NULLPTR), data_(nullptr) {}
MsgData(const bool* data)
: type_(BOOL), data_((void*)data), deleter_(&deleter<BOOL>) {}
MsgData(const std::string* data)
: type_(STRING_STD), data_((void*)data), deleter_(&deleter<std::string>) {}
where deleter_ is a member:
std::function<void(void const*)> deleter_;
and deleter is defined as function template:
template<typename T>
void deleter(void const * data) {
delete static_cast<T const *>(data);
}
Once you have these, your destructor would look like this:
~MsgData() {
if (deleter_) {
deleter_(data_);
}
}
Hope that helps.
So I've solved this problem, but I need your opinion if what I did is best practice.
A simple class holds a vector of unique_ptrs to order objects. I will explain the member variable null_unique below.
class order_collection {
typedef std::unique_ptr<order> ord_ptr;
typedef std::vector<ord_ptr> ord_ptr_vec;
ord_ptr_vec orders;
ord_ptr null_unique;
public:
...
const ord_ptr & find_order(std::string);
....
So I need the users of this class to get access to the order unique_ptr if found. However I'm not going to move the object out of the vector so I'm returning the unique_ptr as const ref. My implementation of the find_order method:
const order_collection::ord_ptr & order_collection::find_order(std::string id) {
auto it = std::find_if(orders.begin(),orders.end(),
[&](const order_collection::ord_ptr & sptr) {
return sptr->getId() == id;
});
if (it == orders.end())
return null_unique; // can't return nullptr here
return *it;
}
Since I'm returning by reference I can't return a nullptr. If I try to do so, I get warning : returning reference to a temporary. And if nothing is found the program crashes. So I added a unique_ptr<order> member variable called null_unique and I return it when find doesn't find an order. This solves the problem and warning is gone and doesn't crash when no order is found.
However I'm doubting my solution as it make my class ugly. Is this the best practice for handling this situation?
You should only return and accept smart pointers when you care about their ownership semantics. If you only care about what they're pointing to, you should instead return a reference or a raw pointer.
Since you're returning a dummy null_unique, it is clear that the caller of the method doesn't care about the ownership semantics. You can also have a null state: you should therefore return a raw pointer:
order* order_collection::find_order(std::string id) {
auto it = std::find_if(orders.begin(),orders.end(),
[&](const order_collection::ord_ptr & sptr) {
return sptr->getId() == id;
});
if (it == orders.end())
return nullptr;
return it->get();
}
It doesn't really make sense to return a unique_ptr here, reference or otherwise. A unique_ptr implies ownership over the object, and those aren't really the semantics being conveyed by this code.
As suggested in the comments, simply returning a raw pointer is fine here, provided that your Project Design explicitly prohibits you or anyone on your team from calling delete or delete[] outside the context of the destructor of a Resource-owning object.
Alternatively, if you either have access to Boost or C++17, a std::optional<std::reference_wrapper<order>> might be the ideal solution.
std::optional<std::reference_wrapper<order>> order_collection::find_order(std::string id) {
auto it = std::find_if(orders.begin(),orders.end(),
[&](const order_collection::ord_ptr & sptr) {
return sptr->getId() == id;
});
if (it == orders.end())
return {}; //empty optional object
return **it; //will implicitly convert to the correct object type.
}
/*...*/
void func() {
auto opt = collection.find_order("blah blah blah");
if(!opt) return;
order & ord = opt->get();
/*Do whatever*/
}
(EDIT: In testing on the most recent version of MSVC 2017, it looks like std::reference_wrapper<T> will happily do an implicit conversion to T& if you tell it to. So replacing opt->get() with *opt should work exactly the same.)
As long as I'm here, I might point out that a std::vector<std::unique_ptr<type>> object has a very "Code Smell" sense to it. std::vector<type> implies ownership of the object as is, so unless you have a good reason to prefer this (maybe the objects are large, unmovable/uncopyable, and you need to insert and remove entries frequently? Maybe this is a polymorphic type?), you're probably better off reducing this to a simple std::vector.
EDIT:
The boost version is subtly different, because boost::optional has no restrictions against "optional references", which are specifically forbidden by the C++ Standard Library's version of std::optional. The boost version is actually going to be slightly simpler:
//return type changes, nothing else changes
boost::optional<order&> order_collection::find_order(std::string id) {
auto it = std::find_if(orders.begin(),orders.end(),
[&](const order_collection::ord_ptr & sptr) {
return sptr->getId() == id;
});
if (it == orders.end())
return {}; //empty optional object
return **it; //will implicitly convert to the correct object type.
}
/*...*/
//Instead of calling opt->get(), we use *opt instead.
void func() {
auto opt = collection.find_order("blah blah blah");
if(!opt) return;
order & ord = *opt;
/*Do whatever*/
}
I'm trying to create a wrapper for an std::vector (or any other container from STL, if possible) that can "lock" and "unlock" the const state of a vector that it's holding.
For example, if I create an object of that wrapper, I want to be able to do something like this:
int main()
{
ConstLockVectorWrapper<int> myWrapper(std::vector<int>{}); // Here I pass an empty vector in the constructor parameters,
// which means that my wrapper will be holding an empty vector
// By default the vector inside my wrapper is not locked,
// I can change its size and the values that it holds
myWrapper.get().push_back(10); // ok
myWrapper.get().push_back(20); // ok
myWrapper.get().at(0) = 5; // ok
print(myWrapper.get()); // Prints 5 20
myWrapper.lock(); // Now I made the vector inside my wrapper unchangable
myWrapper.get().push_back(30); // error, the vector is locked
myWrapper.get().at(0) = 55; // error
print(myWrapper.get()); // ok
myWrapper.unlock(); // Now I can change my vector's size and its values again
_getch();
return 0;
}
The only solution (that's not working, unfortunately) I've got, is to create a const reference (const std::vector<T> &) and a regular reference (td::vector<T> &) inside a wrapper class, and bound them to the main vector in our wrapper class.
So, this is what I've done:
template <typename T>
class ConstLockVectorWrapper {
public:
ConstLockVectorWrapper(const std::vector<T> & vec)
: wrappedVector(vec), wrappedVectorRef(wrappedVector), wrappedVectorConstRef(wrappedVector), constLock(false)
{}
void lock()
{
if (constLock) // if the vector is already locked, we just exit the function
return;
// else we lock the vector
constLock = true;
}
void unlock()
{
if (!constLock) // if the vector is already unlocked (changable), we just exit the function
return;
// else we unlock the vector
constLock = false;
}
return_type get() // I need to return a const std::vector<T> & if constLock == true, and std::vector<T> & otherwise, what return type should I put in here?
{
if (constLock)
return wrappedVectorConstRef;
else
return wrappedVectorRef;
}
private:
bool constLock;
std::vector<T> wrappedVector;
// refs
std::vector<T> & wrappedVectorRef;
const std::vector<T> & wrappedVectorConstRef;
};
Of course, it doesn't work. Just because I don't know what to put in the return type of my get() fucntion.
I've tried using trailing return type, didn't work:
template <typename T>
class ConstLockVectorWrapper {
public:
// ...
private:
bool constLock;
std::vector<T> wrappedVector;
// refs
std::vector<T> & wrappedVectorRef;
const std::vector<T> & wrappedVectorConstRef;
public:
auto get() -> decltype((constLock ? wrappedVectorConstRef : wrappedVectorRef))
{
if (constLock)
return wrappedVectorConstRef;
else
return wrappedVectorRef;
}
};
I can't come up with any solution that will actually work, because I'm not so good at C++ yet.
So I'm asking for your help with my problem. Any suggestions or hints to solve this problem would be appreciated!
Thanks
PS
My main goal is to make my wrapper container-type-independent, so it can "lock" and "unlock" the const state of the container it's holding, independently of its type.
And here's the print() function I used in the first code snippet:
template <typename Container>
void print(const Container & c)
{
for (const auto & var : c)
std::cout << var << std::endl;
}
Fundamentally, a method always returns the same thing. The same type. Every time. It's not possible, in C++, to have a method sometimes return one type, and another type at other times. C++ does not work this way.
So, the initial approach would be to have get() return a proxy object with a state. Using, roughly, the same classes and names from your question:
class return_type {
bool is_const;
std::vector<T> &wrapped_vec;
public:
return_type(bool is_constArg,
std::vector<T> &wrapped_vecArg)
: is_const(is_constArg), wrapped_vec(wrapped_vecArg)
{
}
void push_back(T &&t)
{
if (is_const)
throw std::runtime_error(); // Or, whatever...
wrapped_vec.push_back(std::forward<T>(t));
}
// return_type will have to implement, and baby-sit all other
// methods you wish to invoke on the underlying vector.
};
return_type get()
{
return return_type(constLock);
}
This is simple, but crude and somewhat tedious. You would have to implement every std::vector method you need to use in the return_type proxy.
A better approach would be to take advantage of C++11 lambdas. This will avoid the need to reimplement every wheel, at an expense of some additional code bloat. But, big deal. RAM is cheap, these days. Instead of get() and return_type, you will now be implementing two template methods in your wrapper: get_const() and get_mutable(). Each one of them takes a lambda parameter and invokes it and, if all goes well, passing it the wrapped vector as an argument:
template<typename lambda>
void get_mutable(lambda &&l)
{
if (constLock)
throw std::runtime_error(); // Or, whatever...
l(wrapped_vec);
}
template<typename lambda>
void get_const(lambda &&l)
{
l(const_cast<const std::vector<T> &>(wrapped_vec));
}
The only thing you now need to decide is whether you need access a mutable or a constant vector, and pick the right getter:
myWrapper.get_mutable( [&](std::vector<int> &v) { v.push_back(10); } );
get_mutable() throws an exception if the vector is locked at this time. Otherwise it passes the vector to your lambda. Your lambda does whatever the heck it wants with it, which can be push_back(), or anything else, then returns.
But if you only need read-only access to the vector, use get_const():
int s;
myWrapper.get_const( [&](const std::vector<int> &v) { s=v.size(); } );
Note that get_const() takes care to const_cast the vector, before invoking the lambda, so the lambda will not be able to modify it. This will be enforced at compile-time.
With some additional work, it would also be possible to clean this up a little bit, and have the getter also return whatever lambda returns to the caller, making it possible to do something like this:
int s=myWrapper.get_const( [&](const std::vector<int> &v) { return v.size(); } );
It's possible to have get_const() and get_mutable() be smart enough to figure out if the lambda returns something, and happily pass it back to the caller, whatever it is. And how to do that, I suppose, will have to be another question on stackoverflow.com
P.S. If you don't have C++11, you can just have get_const() and get_mutable() return the wrapped vector (with get_mutable() verifying that it's not locked). This really accomplishes the same thing. The key point is that due to the way that C++ works, you will have to disambiguate, in advance, whether you need constant or mutable access.
I was working on a similar problem a while back. In multithreaded environment sometimes its more efficient to have different types of lock depending on whether you are reading or writing. But the locking is entirely cooperative. It is possible to obtain a read-only lock but still accidentally write to the object.
One solution I am exploring is, instead of obtaining a read-only lock from an object, getting a read-only wrapper of my object so that not only is the object read-only locked it is also only possible to call read-only (const) methods on the object.
The basic wrapper I used was something like this:
template<typename T>
class ConstWrapper
{
T& v;
public:
ConstWrapper(T& v): v(v) {}
T const& operator* () const { return v; } // return const reference
T const* operator->() const { return &v;} // return const pointer
};
By overloading the * and -> operators you get a kind of pass through ability to call the enclosed objects methods - but using pointer semantics (though its not a pointer).
std::vector<int> v {1, 2, 3, 4}; // not const
ConstWrapper<std::vector<int>> cv(v); // const wrapper
std::cout << cv->at(0) << '\n'; // okay at() is a const method
cv->push_back(8); // ILLEGAL!! push_back() is not a const method
Consider the following code:
// A non-copyable, non-movable aggregate
struct Strange
{
const int & i;
char & c;
};
class Container
{
private:
int my_i;
char my_c;
Strange thing;
public:
// Valid, because both `my_i´ and `my_c´ are non-const
// objects to which both references can be bound.
explicit
Container
( )
noexcept
: thing{ my_i , my_c }
{ }
// How could this be implemented?
auto &
operator=
( const Container & that )
noexcept
{
this->my_i = that->my_i;
this->my_c = that->my_c;
// What to do with `thing´?
return *this;
}
};
Possible solutions
Dynamically allocate the Strange object
class Container
{
private:
int my_i;
char my_c;
Strange * thing;
public:
// Note that it isn't exception safe.
explicit
Container
( )
: thing(new Strange{ my_i , my_c })
{ }
auto &
operator=
( const Container & that )
noexcept
{
this->my_i = that->my_i;
this->my_c = that->my_c;
delete this->thing;
this->thing = new Strange { this->my_i , this->my_c };
return *this;
}
};
Concerns:
Not efficient.
Not safe: allocation may fail and throw.
Dangerous: great care has to be taken not to leak memory.
Using a smart pointer (i.e. std::unique_ptr) would solve only the last point, aside from making the code more readable.
Use placement new
class Container
{
private:
int my_i;
char my_c;
Strange thing;
public:
explicit
Container
( )
noexcept
: thing{ my_i , my_c }
{ }
auto &
operator=
( const Container & that )
noexcept
{
this->my_i = that.my_i;
this->my_c = that.my_c;
// Placement new is exception safe, and so is
// construction of `Strange´.
this->thing.~Strange();
new(&this->thing) Strange { this->my_i , this->my_c };
return *this;
}
};
Concerns:
Will Strange's destructor free the memory taken by thing?
I think that, just as constructors, destructors are not responsible for memory management. Moreover, my code seems to work fine. However, I would like clarification on this.
What about memory alignment?
My guess is that, since it replaces an existing object of the same type, memory would already be aligned. Is this correct?
Would Container's destructor take care of destructing thing?
Questions
Aside from corroborating and/or refuting the concerns I explained above, I would like to know if there are other alternatives. If so, please, give an example implementation.
This question arose when working on a class that ought to offer an interface similar to that of std::unordered_map. Instead of reimplementing it, my class encapsulates such container, and just acts as a proxy for most methods: its iterators envelop those provided by the map, and its pair is an aggregate structure with appropiately named members (which are references to the actual data), represented in the examples provided as Strange. Since iterators are required to return references and pointers to the actual data, my custom iterators contain a pair. The problem was modifying it (when incrementing or assigning the iterator). I acknowledge that this probably isn't a good idea, and that those references will impact performance, but am anyway interested in the matter.
Edit
I have just realized that, instead of returning references and pointers to a member custom pair pointing to the actual data (that of the encapsulated map) from my custom iterator, I could return in-place constructed custom pairs (i.e. Strange objects). Often, we do not see that we are in a cave, and instead of exiting it, continue forward :). Excuse me for the noise, I'll mark the question as "Closed".
(If we're talking about moving objects and using the auto keyword, you should add the c++11 tag to your question).
I'm not sure I really understand your question; the example you gave doesn't seem well thought to me; it would be much better to use pointers in Strange.
For example, this compiles and works absolutely fine, and is functionally equivalent to what you want to do I think.
struct Strange
{
Strange()
: i(nullptr), c(nullptr) {}
Strange( const int *_i, const char *_c )
: i(_i), c(_c) {}
const int *i;
const char *c;
};
class Container
{
int my_i;
char my_c;
Strange thing;
public:
Container()
: thing(&my_i,&my_c)
{ }
Container( int i, char c )
: my_i(i), my_c(c), thing(&my_i,&my_c)
{ }
Container( int i, char c, const Strange& s )
: my_i(i), my_c(c), thing(s) // use default copy-constructor
{ }
Container &
operator=
( const Container & that )
{
my_i = that.my_i;
my_c = that.my_c;
thing = that.thing;
return *this;
}
};
int main()
{
Container a(12,24);
Container b(25,42);
b = a;
}
Note that referencing memory within objects is generally dangerous.
For example, using memcpy on this would be a catastrophy.
(Compiled with clang and g++)
Ok so I'm wanting to write a precise 'mark and sweep' garbage collector in C++. I have hopefully made some decisions that can help me as in all my pointers will be wrapped in a 'RelocObject' and I'll have a single block of memory for the heap. This looks something like this:
// This class acts as an indirection to the actual object in memory so that it can be
// relocated in the sweep phase of garbage collector
class MemBlock
{
public:
void* Get( void ) { return m_ptr; }
private:
MemBlock( void ) : m_ptr( NULL ){}
void* m_ptr;
};
// This is of the same size as the above class and is directly cast to it, but is
// typed so that we can easily debug the underlying object
template<typename _Type_>
class TypedBlock
{
public:
_Type_* Get( void ) { return m_pObject; }
private:
TypedBlock( void ) : m_pObject( NULL ){}
// Pointer to actual object in memory
_Type_* m_pObject;
};
// This is our wrapper class that every pointer is wrapped in
template< typename _Type_ >
class RelocObject
{
public:
RelocObject( void ) : m_pRef( NULL ) {}
static RelocObject New( void )
{
RelocObject ref( (TypedBlock<_Type_>*)Allocator()->Alloc( this, sizeof(_Type_), __alignof(_Type_) ) );
new ( ref.m_pRef->Get() ) _Type_();
return ref;
}
~RelocObject(){}
_Type_* operator-> ( void ) const
{
assert( m_pRef && "ERROR! Object is null\n" );
return (_Type_*)m_pRef->Get();
}
// Equality
bool operator ==(const RelocObject& rhs) const { return m_pRef->Get() == rhs.m_pRef->Get(); }
bool operator !=(const RelocObject& rhs) const { return m_pRef->Get() != rhs.m_pRef->Get(); }
RelocObject& operator= ( const RelocObject& rhs )
{
if(this == &rhs) return *this;
m_pRef = rhs.m_pRef;
return *this;
}
private:
RelocObject( TypedBlock<_Type_>* pRef ) : m_pRef( pRef )
{
assert( m_pRef && "ERROR! Can't construct a null object\n");
}
RelocObject* operator& ( void ) { return this; }
_Type_& operator* ( void ) const { return *(_Type_*)m_pRef->Get(); }
// SS:
TypedBlock<_Type_>* m_pRef;
};
// We would use it like so...
typedef RelocObject<Impl::Foo> Foo;
void main( void )
{
Foo foo = Foo::New();
}
So in order to find the 'root' RelocObjects when I allocate in 'RelocObject::New' I pass in the 'this' pointer of the RelocObject into the allocator(garbage collector). The allocator then checks to see if the 'this' pointer is in the range of the memory block for the heap and if it is then I can assume its not a root.
So the issue comes when I want to trace from the roots through the child objects using the zero or more RelocObjects located inside each child object.
I want to find the RelocObjects in a class (ie a child object) using a 'precise' method. I could use a reflection approach and make the user Register where in each class his or her RelocObjects are. However this would be very error prone and so I'd like to do this automatically.
So instead I'm looking to use Clang to find the offsets of the RelocObjects within the classes at compile time and then load this information at program start and use this in the mark phase of the garbage collector to trace through and mark the child objects.
So my question is can Clang help? I've heard you can gather all kinds of type information during compilation using its compile time hooks. If so what should I look for in Clang ie are there any examples of doing this kind of thing?
Just to be explicit: I want to use Clang to automatically find the offset of 'Foo' (which is a typedef of RelocObject) in FooB without the user providing any 'hints' ie they just write:
class FooB
{
public:
int m_a;
Foo m_ptr;
};
Thanks in advance for any help.
Whenever a RelocObject is instantiated, it's address can be recorded in a RelocObject ownership database along with sizeof(*derivedRelocObject) which will immediately identify which Foo belongs to which FooB. You don't need Clang for that. Also since Foo will be created shortly after FooB, your ownership database system can be very simple as the order of "I've been created, here's my address and size" calls will show the owning RelocObject record directly before the RelocObject instance's that it owns.
Each RelocObject has a ownership_been_declared flag initialized as false, upon first use (which would be after the constructors have completed, since no real work should be done in the constructor), so when any of those newly created objects is first used it requests that the database update it's ownership, the database goes through it's queue of recorded addresses and can identify which objects belong to which, clear some from it's list, setting their ownership_been_declared flag to true and you will have the offsets too (if you still need them).
p.s. if you like I can share my code for an Incremental Garbage Collector I wrote many years ago, which you might find helpful.