I have a function that effectively does this
void foo(Class** c)
{
// memory checks and stuff
(*c) = new Class();
// more stuff
}
I cannot change this function. To call this function I have to do something like this.
Class* c = nullptr;
foo(&c);
if (c)
{
// stuff
}
delete c;
I would very much prefer to use a std::unique_ptr rather than the raw pointer. However, I don't know how to get the address of the internal pointer. The listing below does not compile, obviously, because I'm trying to take the address of an rvalue.
std::unique_ptr<Class> c = nullptr;
foo(&(c.get()));
if (c)
{
// stuff
}
I realize I could make the raw pointer as well as the unique pointer, call the function, then give the raw pointer to the unique pointer, but I would prefer to not. Is there a way to do what I want to do?
Create a wrapper around foo:
std::unique_ptr<Class> foo()
{
Class* c = nullptr;
foo(&c);
return std::unique_ptr<Class>(c);
}
Your hands are tied by the API of the function.
The best solution I personally see is to do what you said you'd rather not: create the unique_ptr after calling the function.
If you call this function a lot or if you have many functions like it I would create a wrapper function that creates locally the raw pointer and returns unique_ptr.
I'm currently stuck at a very specific problem. I have a map of structs like:
std::map<int, MyStruct> myMap;
typedef struct
{
long a;
int b;
MyObject* object;
} MyStruct;
On the structs creation object is always set to nullptr:
void createNewStruct(int id)
{
MyStruct newStruct{2L, 1, nullptr}; // create with no object
myMap.insert(std::pair(id, newStruct)); // store in map
}
I do this because I may have thousands of structs in the map, but only a few may need an actual "object" which itself is pretty large.
The object itself has a limited lifetime, and it should show if it's currently not shown, and not show if it's currently showing. If the end of the objects lifetime is reached it calls stopped(this):
void doShow(int id)
{
if(myMap[id].object == nullptr)
{
MyObject* newObject = new MyObject();
connect(object, SIGNAL(stopped(MyObject*), this, (objectStopped(MyObject*)); // create callback to delete object later
myMap[id].object = newObject;
// do something with object
}
}
Now if stopped(this) is called I try to clean up:
void objectStopped(MyObject* object)
{
// do something with object
delete object;
object = nullptr; //????
}
But obviously this is not working as intended because the check to nullptr won't ever be true again.
So what i want to achieve is: I have a map with a lot of structs, but only few of these structs need the object. How can I create and delete this object correctly?
If you have a C++11 compiler (which you should), you can make use of the id:
connect(object,
SIGNAL(stopped(MyObject*),
this,
[]() { delete myMap[id]; myMap[id] = nullptr; });
I think the best way to achieve this, is giving to MyStruct the ownership of MyObject, and not using external functions to manage that allocation.
If you do that, your design in general will improve.
For example you can give to MyStruct some functions to manage the creation of the MyObject structure: createObject() to create one, or destroyObject() to destroy it, a function to check if the object is present, and you can give to MyStruct his own doShow() member function, so your external doShow(int id) function will get the correct MyStruct for that specific 'id' and then will call MyStruct::doShow() nothing more.
When you destroy a MyStruct object, it will also deallocate its MyObject, if any, automatically, without worrying about it will callbacks, signal/slots mechanisms etc.
So, bottom line: I'd just make MyStruct object smarter, and giving to it the complete ownership of the MyObject class. I'm sure this will improve the overall design.
So I have a C++ function to which I pass a pointer to a base class, like:
void DoStuffAndAssignPtr(MyBase* ptr)
{
MyBase* p;
//do stuff
if (stuff was awesome) p = new MyAwesome();
else p = new MyBase();
//vftable of p before the return is MyAwesome
(*ptr) = (*p);
}
Now we need to invoke some virtual method that 'MyAwesome' and 'MyBase' implement differently. However, when checking the return value, as below:
void mainly()
{
MyBase* passMe = new MyBase();
DoStuffAndAssignPtr(passMe);
//now passMe is always being returned with MyBase's vftable
}
We can see that 'passMe' is always a 'MyBase' (as far as the vftable shows while debugging in VS). Can anyone provide any guidance as to why this is happening, and how I can ensure that 'passMe' will invoke 'MyAwesome' implementations of virtual methods?
The problem is with the use of (*ptr)=(*p). You should use ptr=p.
Only pointer and reference have polymorphism. When you use dereference (the star *), you lose this property, and only the base part is copied from p to ptr. This is because ptr only have space for that part of information.
You have object slicing issue, below statement slices MyAwesome object to MyBase:
(*ptr) = (*p)
You only pass MyBase* to DoStuffAndAssignPtr and tried to allocate a new pointer which will only overwrite the copy of function parameter. You need to pass the reference of the pointer instead.
void DoStuffAndAssignPtr(MyBase*& ptr);
^^^
Also as passMe is allocated by new outside DoStuffAndAssignPtr already, you created another membory for ptr inside DoStuffAndAssignPtr which will cause memory leak.
A better solution is:
MyBase* MakeAClass()
{
if (stuff was awesome)
{
return new MyAwesome();
}
return new MyBase();
}
int main()
{
MyBase* passMe = MakeBase()
}
I'm trying to build a struct with a constructor and destructor in C++ (is that a bad thing to do? Should I use a class instead?), because I would hate to write unnecessary 10 lines of delete struct.member every time the members should be deallocated
The members of the struct are mostly pointers to other types.
However, apart from the option of the member pointer being a unique pointer, I also want to be able to assign a copy of another pointer to a member pointer in the struct. Consequently, if I try to deallocate that memory inside the destructor of the struct, it could have already been deallocated, causing a crash. (especially if the pointer copied was from another object of the same struct)
ptr to ptr-types instead of ptr-types in the struct wouldn't solve the problem either (I think), since I also want to allow the member to be able to be a unique pointer to an object.
A possible solution that I've thought of, is to have both a ptr-to-ptr and a ptr to be pointed to by the ptr-to-ptr. But that would just be rather inefficient.
What would my best solution be?
I hope (but doubt) my question is clear enough.
Here's some example code that might help.
struct GraphicsDesc
{
public:
ID3D11VertexShader* pSolidColorVS;
ID3D11PixelShader* pSolidColorPS;
ID3D11InputLayout* pInputLayout;
ID3D11ShaderResourceView* pColorMap;
ID3D11SamplerState* pSampler;
ID3D11BlendState* pBlendState;
ID3D11Buffer* pVertexBuffer;
UINT VertexSize;
D3D_PRIMITIVE_TOPOLOGY Topology;
GraphicsDesc()
{
pSolidColorVS = nullptr;
pSolidColorPS = nullptr;
pInputLayout = nullptr;
pColorMap = nullptr;
pSampler = nullptr;
pBlendState = nullptr;
pVertexBuffer = nullptr;
VertexSize = 0;
Topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
}
virtual ~GraphicsDesc()
{
if (pVertexBuffer) {
pVertexBuffer->Release();
}
if (pBlendState) {
pBlendState->Release();
}
if (pSampler) {
pSampler->Release();
}
if (pColorMap) {
pColorMap->Release();
}
if (pInputLayout) {
pInputLayout->Release();
}
if (pSolidColorPS) {
pSolidColorPS->Release();
}
if (pSolidColorVS) {
pSolidColorVS->Release();
}
}
};
All of those pointer data members are pointers to COM types that are reference counted. Release does not necessarily destroy the pointed-to object. It decrements the reference count and only destroys the object if there are no more references to it.
Rather than using raw pointers and calling AddRef and Release yourself, you should use CComPtr and CComQIPtr, which automate the reference counting.
Can boost::shared_ptr release the stored pointer without deleting it?
I can see no release function exists in the documentation, also in the FAQ is explained why it does not provide release function, something like that the release can not be done on pointers that are not unique. My pointers are unique. How can I release my pointers ?
Or which boost smart pointer class to use that will allow me releasing of the pointer ?
I hope that you won't say use auto_ptr :)
Don't. Boost's FAQ entry:
Q. Why doesn't shared_ptr provide a release() function?
A. shared_ptr cannot give away ownership unless it's unique() because the other copy will still destroy the object.
Consider:
shared_ptr<int> a(new int);
shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2
int * p = a.release();
// Who owns p now? b will still call delete on it in its destructor.
Furthermore, the pointer returned by release() would be difficult to deallocate reliably, as the source shared_ptr could have been created with a custom deleter.
So, this would be safe in case it's the only shared_ptr instance pointing to your object (when unique() returns true) and the object doesn't require a special deleter. I'd still question your design, if you used such a .release() function.
You could use fake deleter. Then pointers will not be deleted actually.
struct NullDeleter {template<typename T> void operator()(T*) {} };
// pp of type some_t defined somewhere
boost::shared_ptr<some_t> x(pp, NullDeleter() );
Kids, don't do this at home:
// set smarty to point to nothing
// returns old(smarty.get())
// caller is responsible for the returned pointer (careful)
template <typename T>
T* release (shared_ptr<T>& smarty) {
// sanity check:
assert (smarty.unique());
// only one owner (please don't play games with weak_ptr in another thread)
// would want to check the total count (shared+weak) here
// save the pointer:
T *raw = &*smarty;
// at this point smarty owns raw, can't return it
try {
// an exception here would be quite unpleasant
// now smash smarty:
new (&smarty) shared_ptr<T> ();
// REALLY: don't do it!
// the behaviour is not defined!
// in practice: at least a memory leak!
} catch (...) {
// there is no shared_ptr<T> in smarty zombie now
// can't fix it at this point:
// the only fix would be to retry, and it would probably throw again
// sorry, can't do anything
abort ();
}
// smarty is a fresh shared_ptr<T> that doesn't own raw
// at this point, nobody owns raw, can return it
return raw;
}
Now, is there a way to check if total count of owners for the ref count is > 1?
You need to use a deleter that you can request not to delete the underlying pointer.
See this answer (which has been marked as a duplicate of this question) for more information.
To let the pointer point to nothing again, you can call shared_ptr::reset().
However, this will delete the object pointed to when your pointer is the last reference to the object. This, however, is exactly the desired behaviour of the smart pointer in the first place.
If you just want a reference that does not hold the object alive, you can create a boost::weak_ptr (see boost documentation). A weak_ptr holds a reference to the object but does not add to the reference count, so the object gets deleted when only weak references exist.
The basis of sharing is trust. If some instance in your program needs to release the raw pointer, it is almost for sure that shared_ptr is the wrong type.
However, recently I wanted to do this too, as I needed to deallocate from a different process-heap. In the end I was taught that my older decision to use some std::shared_ptr was not thought-out.
I just routinely used this type for cleanup. But the pointer was just duplicated on a few places. Actually I needed a std::unique_ptr, which (suprise) has a release function.
Forgive them for they know not what they do.
This example works with boost::shared_ptr and msvs std::shared_ptr without memory leaks!
template <template <typename> class TSharedPtr, typename Type>
Type * release_shared(TSharedPtr<Type> & ptr)
{
//! this struct mimics the data of std:shared_ptr ( or boost::shared_ptr )
struct SharedVoidPtr
{
struct RefCounter
{
long _Uses;
long _Weaks;
};
void * ptr;
RefCounter * refC;
SharedVoidPtr()
{
ptr = refC = nullptr;
}
~SharedVoidPtr()
{
delete refC;
}
};
assert( ptr.unique() );
Type * t = ptr.get();
SharedVoidPtr sp; // create dummy shared_ptr
TSharedPtr<Type> * spPtr = (TSharedPtr<Type>*)( &sp );
spPtr->swap(ptr); // swap the contents
ptr.reset();
// now the xxx::shared_ptr is empy and
// SharedVoidPtr releases the raw poiter but deletes the underlying counter data
return t;
}
You can delete the shared pointer, which seems much the same to me. If pointers are always unique, then std::auto_ptr<> is a good choice. Bear in mind that unique pointers can't be used in STL containers, since operations on them do a lot of copying and temporary duplication.
I'm not entirely sure if your question is about achieving this, but if you want behaviour from a shared_ptr, where, if you release the value from one shared_ptr, all the other shared pointers to the same value become a nullptr, then you can put a unique_ptr in a shared_ptr to achieve that behaviour.
void print(std::string name, std::shared_ptr<std::unique_ptr<int>>& ptr)
{
if(ptr == nullptr || *ptr == nullptr)
{
std::cout << name << " points to nullptr" << std::endl;
}
else
{
std::cout << name << " points to value " << *(*ptr) << std::endl;
}
}
int main()
{
std::shared_ptr<std::unique_ptr<int>> original;
original = std::make_shared<std::unique_ptr<int>>(std::make_unique<int>(50));
std::shared_ptr<std::unique_ptr<int>> shared_original = original;
std::shared_ptr<std::unique_ptr<int>> thief = nullptr;
print(std::string("original"), original);
print(std::string("shared_original"), shared_original);
print(std::string("thief"), thief);
thief = std::make_shared<std::unique_ptr<int>>(original->release());
print(std::string("original"), original);
print(std::string("shared_original"), shared_original);
print(std::string("thief"), thief);
return 0;
}
Output:
original points to value 50
shared_original points to value 50
thief points to nullptr
original points to nullptr
shared_original points to nullptr
thief points to value 50
This behaviour allows you to share a resource (like an array), then later reuse that resource while invalidating all the shared references to this resource.
Here's a hack that might work. I wouldn't recommend it unless you're in a real bind.
template<typename T>
T * release_shared(std::shared_ptr<T> & shared)
{
static std::vector<std::shared_ptr<T> > graveyard;
graveyard.push_back(shared);
shared.reset();
return graveyard.back().get();
}
If your pointers are indeed unique do use std::unique_ptr or boost::scoped_ptr if the former is not available for your compiler. Otherwise consider combining the use of boost::shared_ptr with boost::weak_ptr. Check out the Boost documentation for details.
I am using Poco::HTTPRequestHandlerFactory which expects to return a raw HTTPRequestHandler*, the Poco framework deletes the handler once the request finishes.
Also using DI Sauce project to create the controllers, however the Injector returns shared_ptr which I cannot return directly, and returning handler.get() is no good either since the as soon as this function returns the shared_ptr goes out of scope and deletes then handler before its executed, so here is a reasonable (I think) reason to have a .release() method. I ended up creating a HTTPRequestHandlerWrapper class as follows :-
class HTTPRequestHandlerWrapper : public HTTPRequestHandler {
private:
sauce::shared_ptr<HTTPRequestHandler> _handler;
public:
HTTPRequestHandlerWrapper(sauce::shared_ptr<HTTPRequestHandler> handler) {
_handler = handler;
}
virtual void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response) {
return _handler->handleRequest(request, response);
}
};
and then the factory would
HTTPRequestHandler* HttpHandlerFactory::createRequestHandler(const HTTPServerRequest& request) {
URI uri = URI(request.getURI());
auto path = uri.getPath();
auto method = request.getMethod();
sauce::shared_ptr<HTTPRequestHandler> handler = _injector->get<HTTPRequestHandler>(method + ":" + path);
return new HTTPRequestHandlerWrapper(handler);
}
which satisfied both Sauce and Poco and works nicely.
I needed to pass a pointer through async handlers and to keep the self-destruct behavior in case of failure but the final API expected a raw pointer, so I made this function to release from a single shared_ptr:
#include <memory>
template<typename T>
T * release(std::shared_ptr<T> & ptr)
{
struct { void operator()(T *) {} } NoDelete;
T * t = nullptr;
if (ptr.use_count() == 1)
{
t = ptr.get();
ptr.template reset<T>(nullptr, NoDelete);
}
return t;
}
If ptr.use_count() != 1 you shall get a nullptr instead.
Do note that, from cppreference (bold emphasis mine):
If use_count returns 1, there are no other owners. (The deprecated member function unique() is provided for this use case.) In multithreaded environment, this does not imply that the object is safe to modify because accesses to the managed object by former shared owners may not have completed, and because new shared owners may be introduced concurrently, such as by std::weak_ptr::lock.
Easy solution, increase the reference and then leak the shared_pointer.
boost::shared_ptr<MyType> shared_pointer_to_instance(new MyType());
new boost::shared_ptr<MyType>();
MyType * raw_pointer = shared_pointer_to_instance.get()
This will clearly cause a memory leak of both the shared_ptr and the MyType *