unique_ptr with an API that expects raw pointers? - c++

After about 10 years of using managed memory and functional languages, I'm finally coming home to C++, and smart pointers are confusing the heck out of me. Half of the documentation out there is still regarding the deprecated auto_ptr.
I'm trying to implement this fairly straightforward Bullet "hello world" program:
int _tmain(int argc, _TCHAR* argv[])
{
auto bp = unique_ptr<btBroadphaseInterface>(new btDbvtBroadphase);
auto cc = unique_ptr<btDefaultCollisionConfiguration>(new btDefaultCollisionConfiguration);
auto disp = unique_ptr<btDispatcher>(new btCollisionDispatcher(cc));
}
The btCollisionDispatcher constructor wants a btCollisionConfiguration*, but I'm giving it a unique_ptr to one instead.
What do I normally want to do in this case? If there's a way to "de-smart" the pointer, something tells me that unique_ptr isn't the right smart pointer to use.
C++ was my language of choice before I moved to other things. It's a little shocking coming back and seeing that all the patterns and practices have completely changed.

There is a get() member function that gives you the raw pointer that is held by the unique_ptr. This does not cause the unique_ptr to relinquish the ownership, though, so proper cleanup will still happen (careful with storing that raw pointer!).
There is also a release() member function, which relinquishes ownership. This means that you're back on dumb pointer land and cleanup is all your responsibility.
I can't fathom why the code is using new in the first place and not just using automatic storage objects, but I'm going to pretend there is a reason...

The get member function returns the underling pointer and is fine to use with existing code as long as that code doesn't manage the memory you pass in.

Related

VS2019 | C++ | Shared Pointers | Compiler Warning: The pointer points to memory allocated on the stack

I have inherited a pile of C++ code, saturated with std::shared_ptrs, most [all?] of which are unnecessary and are, I suspect, degrading performance. It is not feasible to change everything in one go, so I'm changing the code in tranches and doing performance tests.
An issue I'm running into is the interface in the method hierarchy between my new "raw" pointer code, and the underlying shared_ptr stuff. A contrived example (I know it could be simplified...):
SomeObject *MyClass::GetSomeObject(const std::string& aString)
{
//for the underlying shared pointer methods
std::shared_ptr<std::string> tmpString = make_shared<std::string>(aString);
//call the method using my local shared pointer
std::shared_ptr<SomeObject> someObj = GetTheObject(tmpString);
//The line below gives compiler warning: "The pointer points to memory allocated on the stack"
return someObj.get(); // a pointer to an object in std::map
}
I know that GetTheObject() is returning a pointer to an object in a persistent std::map, so that memory will be in good standing after we exit GetSomeObject() and the shared pointer [and its wrapped raw pointer] have gone out of scope.
I'm not in the habit of ignoring warnings, SO:
Questions:
Is the warning because the compiler is worried about the scope of the shared pointer rather than the object pointed to? [i.e. could I ignore it in this instance?]
If it is a real problem, are there any neat ways around this (that do not involve building wrapper classes and such workarounds...) ?
If I understand you correctly, you're replacing smart pointers with dumb pointers, in 2021, and you're now facing the exact problem that smart pointers intended to solve.
The warning is 100% accurate, and I'm pleasantly surprised the compiler looked deep enough.
The solution is simple: return a shared_ptr<SomeObject>. If you want efficiency improvements, there are two real improvements possible. C++11 introduced move constructors, and moving shared_ptr is faster than copying. The compiler will use the move ctor for return someObj; since someObj goes out of scope
Secondly, shared_ptr is a heavy-weight alternative to unique_ptr. At times, you may be able to downgrade to the latter.
I have similar code in my project. I agree that the proper solution is probably just to commit fully to the smart pointers and use them properly. However, I don't want to churn through piles of perfectly functional code, but I also want the warnings to go away. I was able to work around the warning with something like:
SomeObject *MyClass::GetSomeObject(const std::string& aString)
{
//for the underlying shared pointer methods
std::shared_ptr<std::string> tmpString = make_shared<std::string>(aString);
//call the method using my local shared pointer
std::shared_ptr<SomeObject> someObj = GetTheObject(tmpString);
SomeObject *pRet = someObj.get();
return pRet; // a pointer to an object in std::map
}
I'm a little worried that at some point the compiler will get smarter and detect that as a warning as well, but it seems OK for now. (Visual Studio 2022 v17.1) Hope that helps!

Correctly using smart pointers

I'm having trouble getting things organized properly with smart pointers. Almost to the point that I feel compelled to go back to using normal pointers.
I would like to make it easy to use smart pointers throughout the program without having to type shared_ptr<...> every time. One solution I think of right away is to make a template class and add a typedef sptr to it so I can do class Derived : public Object < Derived > .. and then use Derived::sptr = ... But this obviously is horrible because it does not work with another class that is then derived from Derived object.
And even doing typedef shared_ptr<..> MyObjectPtr is horrible because then it needs to be done for each kind of smart pointer for consistency's sake, or at least for unique_ptr and shared_ptr.
So what's the standard way people use smart pointers? Because frankly I'm starting to see it as being too much hassle to use them. :/
So what's the standard way people use smart pointers?
Rarely. The fact that you find it a hassle to use them is a sign that you over-use pointers. Try to refactor your code to make pointers the exception, not the rule. shared_ptr in particular has its niche, but it’s a small one: namely, when you genuinely have to share ownership of a resource between several objects. This is a rare situation.
Because frankly I'm starting to see it as being too much hassle to use them. :/
Agreed. That’s the main reason not to use pointers.
There are more ways to avoid pointers. In particular, shared_ptr really only needs to spelled out when you actually need to pass ownership. In functions which don’t deal with ownership, you wouldn’t pass a shared_ptr, or a raw pointer; you would pass a reference, and dereference the pointer upon calling the function.
And inside functions you almost never need to spell out the type; for instance, you can (and should) simply say auto x = …; instead of shared_ptr<Class> x = …; to initialise variables.
In summary, you should only need to spell out shared_ptr in very few places in your code.
I have a lot of code that creates objects dynamically. So using pointers is necessary because the number of objects is not known from the start. An object is created in one subsystem, then stored in another, then passed for further processing to the subsystem that created it. So that I guess means using shared_ptr. Good design? I don't know, but it seems most logical to ask subsystem to create a concrete object that it owns, return a pointer to an interface for that object and then pass it for further processing to another piece of code that will interact with the object through it's abstract interface.
I could return unique_ptr from factory method. But then I would run into trouble if I need to pass the object for processing multiple times. Because I would still need to know about the object after I pass it to another method and unique_ptr would mean that I lose track of the object after doing move(). Since I need to have at least two references to the object this means using shared_ptr.
I heard somewhere that most commonly used smart pointer is unique_ptr. Certainly not so in my application. I end up with using shared_ptr mush more often. Is this a sign of bad design then?

How to pass address of C++ object to C

I'm using Visual Studio 2013 and C++11. I want to pass the address of a C++ object back to C. The C code will treat it as a opaque handle; C will never reference it. The only use will be to pass it back to C++ where it will again be used as a pointer to object.
I'm finding that if I create the object in C++ and pass it back to C, the object will be destroyed because it goes out of scope. As a work around, I created a global variable to hold the object so it won't be destroyed upon returning to C. What is the best practice? Should I use a ref-counted pointer type such as shared_ptr? How? I don't like the idea of casting to size_t or such.
The following is an attempt to demonstrate the question. Code won't work.
extern "C" _declspec(dllexport) void __stdcall SwbHttpListenW(const wchar_t *route, SwbHttpListen **listener)
{
*listener = &SwbHttpListen(route); // new will work but how about without new?
}
[Edited the code to re-ask for a solution not using new.]
How about heap allocating the C++ object using the new operator, and getting its address by using the ampersand (&) operator? By heap allocating the object, you ensure it will never be deleted until you actually use the delete operator on it, and the address could be stored/passed as an int.
A simple example:
int main() {
Person *a = new Person("Paul");
doSomething(a); //Passes the memory address of a to the function doSomething
//...and once you're finished using the object, you have to:
delete a;
return 0;
}
It's always going to be messy when you do this sort of thing, how you handle it really depends upon what you want the lifetime of your c++ object to be and, to a lesser extent, how you are going to get rid of it in the end. But clearly the c++ has to do any destruction, you cannot get the c to do that.
This sort of thing is an example of when it is not necessarily A Bad Thing to have global objects - though of course that means you cannot get rid of it freely. Alternatively, you could create it dynamically using new but you then will need an arrangement between the c and the c++ so that it gets deleted at the right time - you might end up with a global object pointer or maybe the c could pass the pointer back to get it destroyed - that would be the nicest solution.
Some trouble may be if some automated Garbage Collector are in use (it may be in C++). std::declare_reachable , std::undeclare_reachable may help.
Else the trouble really doesn't concern passing a pointer to C. And you need to develop some way to achieve a proper pointers to valid objects at the places where necessary... :-)

understanding the smart pointer boost in c++

I am new to c++ as well as smart pointer.
I have a code like this.
Example* Example::get_instance() {
Example* example = new Example();
return example;
}
I am trying to convert it to smart pointer like this
shared_ptr<Example> Example::get_instance() {
shared_ptr<Example> example (new Example());
return example;
}
Is this the correct way because when i am trying to call this from another class its not working.I am trying to implement a singleton object.
You are creating a new Example object every time the object is requested, That is a memory leak, an you are also returning a different object every time. Try this instead:
Example & Example::get_instance() {
static Example example;
return example;
}
Also please note the following advices for your code:
when creating smart pointers prefer make_shared instead of shared_ptr<YourType>(new YourType(...)). The reason why can be found here. Relevant excerpt:
This function typically allocates memory for the T object and for the
shared_ptr's control block with a single memory allocation (it is a
non-binding requirement in the Standard). In contrast, the declaration
std::shared_ptr p(new T(Args...)) performs at least two memory
allocations, which may incur unnecessary overhead. Moreover,
f(shared_ptr(new int(42)), g()) can lead to memory leak if g
throws an exception. This problem doesn't exist if make_shared is
used.
understand the difference between std::unique_ptr and std::shared_ptr. For your case, a std::unique_ptr would have been better, but there is an even simpler solution to your problem, which I have shown above.
in general, avoid pointers when you can use references instead, they're easier to use and code looks a bit cleaner.
and finally, do you REALLY want a singleton? I just have to be ask. I've been working full-time as a programmer for almost 4 years now. Not that long, I know, but enough to have encountered the situation where I regretted that I or someone else used the Singleton pattern instead of passing the reference to my object down the call chain.
Try to avoid singletons, you may later find your code using the singleton might in the end want to work on multiple instances of your Example object instead of calling Example::get_instance and only work on that single instances. So when you'll have that revelation, (and it might be only a matter of time), you'll have major refactoring ahead of you.
So, "Beware, there be dragons!".

Why and when is worth using pointer to pointer? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How do pointer to pointers work in C?
Hello,
Altough I think I passed the newbie phase in programming I still have some questions that somehow I can't find them explained. Yes, there are plenty of "how to"s overthere but almost always nobody explains why and/or when one technique is useful.
In my case I have discovered that in some cases a pointer to a pointer is used in C++. Is not a pointer to an object enough? Which are the benefits? Where or when should be used a pointer to a pointer? I feel little bit desorientated in this matter.
I hope time experienced expert could respond to this concerns that hopefully is shared by other no so experienced programers. ;-)
Thank you everyone.
Julen.
Well, it is somehow hard to answer to such a general question.
First answer of a C++ programmer will certainly be : Do not use pointers in C++ ! As you have a lot of safer ways to handle problems than pointers, one of your goal will be to avoid them in the first place :)
So pointers to pointers are seldom used in C++. They are mainly used in C. First, because in C, strings are "char*" so when you need a "pointer to a C string" you end with a "char**". Second, as you do not have references in C, when you need to have a function that modify a pointer or that give a pointer as an output value, you need to give a pointer to a pointer parameter. You typically find that in functions that allocate memory, as they give you a pointer to the allocated memory.
If you go the C++ way, try to avoid pointers, you usually have better ways.
my2c
In C, an argument is passed to a function that changes it, through a pointer. You will see the same with C++ for old or legacy code (int main(int argc, char** argv)) , for code that will be accessed from C (COM / XPCOM) or with code that was written by someone used to C (or the C style).
From a "purely C++" standpoint, using pointer to pointer is in most situations a sign of poor coding style, as most situations that require a ** construct can (and should) be refactored to use safer alternatives (like std:: containers, or *& parameters).
I can think of two use cases.
One is arrays as inherited from C. Arrays automatically decay to pointers to their first elements in many cases. If you happen to have an array of pointers, you get a pointer to a pointer for that.
(Something similar can happen when you have a std::vector of pointers, BTW: A pointer is a perfect random access iterator and I have indeed seen std lib implementations using pointers for std::vector<>::iterator. For a std::vector of pointers, v.begin() would return a pointer to a pointer.)
The other is for function arguments. For function arguments, taking something per pointer indicates that callers might call the function even if they don't have an object to pass in; they can pass in NULL then. (Otherwise why take a pointer instead of a reference? See here for more details on this).
Taking a non-const reference to a pointer would indicate that the called function might assign a new address to that pointer.
So taking a pointer to a pointer would indicate that the function might assign a new address to a pointer, if the caller passes in a pointer to it, but is callable with NULL as well.
For example:
void f(int** ppi);
void g(int i);
void h()
{
f(NULL); // call `f()` only for its side-effects
int* pi = NULL;
f(&pi); // call `f()` and get some object in *pi
if(pi)
g(*pi); // use result
}
Where or when should be used a pointer to a pointer?
In a function that optionally may return pointer to caller, if the caller requests that. Frequently used by system APIs, some COM objects, etc.
int f(void** p = 0){
//.......
}
If caller provides p, then function passes pointer through p. If caller doesn't provide p, then no pointer is returned. May be useful for debugging purposes in certain situations.
Which are the benefits?
The question is too broad. Look, it is a VERY simple technique without some kind of mysterious benefits. You use it when you have to. That's all. There is no hidden meaning and no secret advantages of this concept - it is equivalent to asking "what are benefits of using letter \"e\" in english language".
Pointers to pointers have most relevance in C. Seldomly, you need them in C++. There you can work with containers from the std lib or with references.
There are two popular use cases in C though:
An array of pointers, most prominently used as argv to main(): the pointer gives the address to the array of argument strings (type char*). In C, the [] operators work on pointers to anything as pointers to anything are seen as an equivalent to arrays.
A function argument denoting a place where to store the address of something. Use case: In C, the return value is often used for error handling or state information. Arguments are used for carrying the payload. One example: A function "returns" an address to newly allocated memory, but using an argument. You give the function a pointer to the pointer that should afterwards point to the data. The function overwrites that space and for that, it needs a pointer to a pointer.
You only use them when employing manual memory management, something that's rare as hell in C++, therefore they're pretty useless. Even regular pointers are of questionable value in the majority of scenarios.
There're actually two use cases.
First, is when you call a function that has to return more than one value, some of which, are pointers. Then, you would provide her with an address of a pointer, so it could fill in the pointed pointer:
int *p1 = 0, *p2 = 0, *p3 = 0;
multi_malloc(&p1, &p2, &p3); // Allocates three pointers
Second is when you want to do sparse 2d arrays:
int main(int argc, char **argv)
This is a pointer to pointer. argv[i] is a pointer to char. This way, argv[i][j] is a char j in row i.
You will be happy to hear that there're nearly zero uses for pointer to pointer to pointer. int ***p; is almost never useful.