In my WinRT API I have to create and return HSTRING values. So far I have been using WindowsCreateString to create HSTRING value and deleting it manually with WindowsDeleteString.
WindowsCreateStringReference looks quite handy in terms one does not have to delete HSTRING manually.
You don't need to call the WindowsDeleteString function to de-allocate a fast-pass HSTRING created by the WindowsCreateStringReference function.
Can anyone elaborate on what is fast-pass string and how and when it actually gets de-allocated?
Another question that comes here is when should I prefer WindowsCreateString over WindowsCreateStringReference?
A 'fast-pass' string doesn't manage the lifetime of its string - it simply creates a wrapper around whatever underlying string you give it. This wrapper is very lightweight.
This means 2 things - firstly you don't need to delete the HSTRING (as it doesn't own the underlying string) but more importantly you must keep the underlying string alive and unchanged whilst the fast-pass string is being used.
So its useful for if you already have a string (say a const char* in the rodata section, or from another source who's lifetime is strictly greater than the lifetime of the HSTRING). But its just an optimisation to avoid a copy.
MY recommendation - if you only care about lifetime and correctly free'ing the string when done - is to use Microsoft::WRL::Wrapper::HString class which provides a nice C++ style RAII wrapper around raw HSTRING's and will correctly free them when done. Then using member functions Detach, Get, GetAddressOf, etc you can then interact with other APIs which expect raw HSTRINGs.
If you do care about speed aswell there is always a Microsoft::WRL::Wrapper::HStringReference class which duplicates the WindowsCreateStringReference funcitonality, but again with a nice c++ RAII object.
Related
Suppose I have an API-border function that creates and returns an object:
<?> createOneObject();
What would be the best way to return the object to the caller?
Return the raw MyObject* and let the caller handle the pointer herself
Return std::shared_ptr<MyObject>
Something else?
Depends.
In general, returning a raw pointer is bad, because the type itself does not communicate ownership. Should the user delete the pointer? If yes, then how? If not, then when does the library do it? How does the user know if the pointer is still valid? Those things have to be documented, and lazy programmers might skip reading the docs. But, if your API must be callable from C or other languages, then a raw pointer may be the only option.
Shared pointer might be useful in special cases, but they do have overhead. If you don't need shared ownership, then use of a shared pointer may be overkill.
Unique pointer is what I would use unless there is specific reason to use something else.
Although, that assumes that a pointer should be returned in the first place. Another great option could be to return an object.
To be a bit more concrete: I have a player class that just stores an id and just offers lots of methods. In this case you would prefer to return by value?
Most definitely.
You have 2 options (without any nasty drawbacks):
C Style
Have a matching void destroyOneObject(MyObject* object); that cleans up the resource. This is the proper choice when destroying the object isn't as simple as deleting it (e.g. needs to be unregistered at some manager class).
Smart pointer
When all that needs to happen is to delete the object, return a std::unique_ptr<MyObject>. This uses RAII to clean up the object, and fits modern C++ a lot better.
The bad solutions
Don't return a raw pointer and call delete on it. You cannot guarantee that the delete matches the new that was used to create the object. It also doesn't communicate very well if you are supposed to delete it in the first place.
Don't use shared pointers. They are complete overkill in almost any situation, and are usually the result of a lack of understanding of an application's structure.
I have a basic design that consists of three classes : A Data class, A Holder class wich holds and manages multiple Data objects, and a Wrapper returned by the Holder wich contains a reference to a Data object.
The problem is that Wrapper must not outlive Holder, or it will contain a dangling reference, as Holder is responsible for deleting the Data objects. But as Wrapper is intended to have a very short lifetime (get it in a function, make some computation on its data, and let it go out of scope), this should not be a problem, but i'm not sure this is a good design.
Here are some solutions i thought about:
-Rely on the user reading the documentation, technically the same thing happens with STL iterators
-Using shared_ptr to make sure the data lasts long enought, but it feels like overkill
-Make Wrapper verify its Holder still exists each time you use it
-Any idea?
(I hope everyone can understand this, as english is not my native language)
Edit : If you want to have a less theoric approach, this all comes from a little algorithm i'm trying to write to solve Sudokus, the Holder is the grid, the Data is the content of each box (either a result or a temporary supposition), and the Wrapper is a Box class wich contains a reference to the Data, plus additional information like row and column.
I did not originally said it because i want to know what to do in a more general situation.
Only ever returning a Wrapper by value will help ensure the caller doesn't hold onto it beyond the calling scope. In conjunction with a comment or documentation that "Wrappers are only valid for the lifetime of the Holder that created them" should be enough.
Either that or you decide that ownership of a Data is transferred to the Wrapper when the Wrapper is created, and the Data is destroyed along with the Wrapper - but what if you want a to destroy a Wrapper without deleting the Data? You'd need a method to optionally relinquish ownership of the Data back to the Holder.
Whichever you choose, you need to decide what owns (ie: is responsible for the lifetime of) Data and when - once you've done that you can, if you want, use smart pointers to help with that management - but they won't make the design decision for you, and you can't simply say "oh I'll use smart pointers instead of thinking about it".
Remember, if you can't manage heap memory without smart pointers - you've got no business managing heap memory with them either!
To elaborate on what you have already listed as options,
As you suggested, shared_ptr<Data> is a good option. Unless performance is an issue, you should use it.
Never hold a pointer to Data in Wrapper. Store a handle that can be used to get a pointer to the appropriate Data object. Before Data is accessed through Wrapper, get a pointer the Data object. If the pointer is not valid, throw an exception. If the pointer is valid, proceed along the happy path.
I find it convenient to (and have a lot of code which) wrappers some storage object in an allocation adapter, and then this allocation adapter is used commonly to scope the guaranteed backstore in a managing object for its lifetime, which is normally the lifetime of the function call.
This seems to be using a nonstandard VisualStudio extension, however, and I'm curious as to what is a better paradigm and why..
e.g. a lot of our code still uses CString. One of the features of a CString is the ability to lock its contents so that you can take a non-const pointer into the underlying buffer and manipulate it directly - a'la C library functions.
This makes it very easy to use a CString for its automatic resource management, but still interface to legacy libraries / code which needed a writable character buffer. However, locking the buffer is not itself an RAII operation, so I made an RAII class to perform that function (like taking on a lock):
// replaces each occurrence of any of the given list of characters with a specified replacement character in-place
inline void ReplaceAll(CStringW & str, const wchar_t * chsOld, const wchar_t chNew)
{
ReplaceAll(make_autobuffer(str), chsOld, chNew);
}
The code behind make_autobuffer is rather long-winded, but the idea boils down to returning an object that holds a lock on the underlying string's buffer, and will ask the str to release that buffer lock on its destruction, thus releasing the buffer back to control by the CString.
This is a trivial idea, and the implementation is fairly trivial as well (lots of boiler plate to make it robust wrt wide/narrow strings, and variations that take a fixed buffer size or not, and some debugging helpers, etc.).
But more generally speaking, I have often found it very useful to have a class which takes a non-const reference to an instance of something, and wrappers that instance in some sort of mutable adapter layer, and then releases the underlying entity upon termination.
The question is whether there is a better way to accomplish this than having to create a named variable to do the adaptation:
// replaces each occurrence of any of the given list of characters with a specified replacement character in-place
inline void ReplaceAll(CStringW & str, const wchar_t * chsOld, const wchar_t chNew)
{
auto adapter = make_autobuffer(str);
ReplaceAll(adapter, chsOld, chNew);
}
This works, and doesn't violate the standard. I'm no longer trying to pass a non-const object by ref from a temp object - since I've forced the temp object into being less temporary by naming it.
But... that seems silly. At the end of the day, doing the above doesn't change the meaning as far as I can tell. And if the VisualStudio allowance was non-standard, then is there a better standard way that isn't so silly?
But... that seems silly. At the end of the day, doing the above doesn't change the meaning as far as I can tell.
Yes it is quite different. However, had you written
auto const& adapter = make_autobuffer(str);
ReplaceAll(adapter, chsOld, chNew);
that would be the same as
ReplaceAll(make_autobuffer(str), chsOld, chNew);
(consider what happens if the copy constructor isn't accessible for the return type of make_autobuffer).
WARNING I just realized we know nothing about what make_autobuffer actually returns. Let me state my assumption: I assume you return a RAII wrapper class with implicit conversion to the parameter type expected by the ReplaceAll function (e.g. char const*¹)
Onto the "main question" - this seems pretty vague. I think you're talking about the MSVC non-standard extension to "lifetime extensions of temporaries when bound to non-const references".
I don't see where that comes in in the code you showed, for the simple reason that you show make_autobuffer being called inside the parameter list. As such, the temporary is guaranteed to exist until after that function call returned anyways, no need to bind/name things to achieve that. Not even in standard c++03.
If you wish to extend the lock to beyond the function call, then yes, name the RAII handle.
Similar design points in the standard library (and Boost counterparts):
std::lock_guard needs to be named to keep the lock beyond the end of the containing full expression
std::async returns a future that needs to be kept in a named variable if you want any semblance of actual async execution (otherwise, the destructor of the future still causes immediate blocking execution)
¹ LPCTSTR in your region?
Ultimately what I chose to do to solve this was to change from using Wrapper & to Wrapper (by copy / move).
Passing a non-const wrapper by ref is a clear violation of C++ argument rules. Having to declare it explicitly was annoying. Passing it by value meant that I could take advantage of Cx11's move rules and maintain no copies for a CStringAutoBuffer (and other similar types of temporary wrapper objects), but still create one on the fly without having to explicitly name one locally.
This preserves const correctness as well.
Overall, a happy resolution to this genre of issue. :)
I am trying to embed lua in an existing C++ application and have made a standard procedure for it by inheriting from a class that does the work.
The serious problem I see is that if the exposed object gets deallocated or deleted in the C++ environment then a call from Lua will cause crashes. If the memory is being deleted by the program using 'delete' then I can maybe write a wrapper on delete to take care of deallocation in Lua as well, but if the memory was allocated by C++ and deallocated when the appropriate variable is out of scope I don't see a way on how to find that out and then take appropriate actions in the lua space, anybody has any ideas on this?
Thanks.
In general, virtually every Lua wrapper has some way to decide who owns what memory. That is, whether an object is owned by (and therefore will be deleted by) Lua or by your application.
If you have given Lua a pointer to an object that C++ owns, then you must find a way to ensure that Lua does not use this pointer past the point where C++ deletes it. There are several ways to avoid this. One way is to transfer ownership to Lua.
Another way is to use a boost/std::shared_ptr, which allows you to share ownership between C++ and Lua. If you're manually doing this, then you are creating some non-light userdata which is the size of a shared_ptr in Lua. You attach a cleanup metamethod to it that will destroy the shared_ptr, and you use placement-new to construct the shared_ptr on the Lua userdata. Luabind actually has this built-in as a feature: if you pass a shared_ptr to Lua, then they both share ownership of the memory.
You could also use a boost/std::weak_ptr. This is an object that you query to get a shared_ptr. The idea is that you're not supposed to keep the pointer around; you query it temporarily as needed, but you only store the weak_ptr permanently. If the object has lost all of its shared_ptr references, then querying the weak_ptr will return a null pointer.
You will have to use an RAII wrapper that can bind to the Lua instance using the registry and expose the values to Lua using a table- you can remove an internal pointer from it when you're done.
template<typename T> class LuaExposedValue {
T t;
lua_State* ls;
public:
LuaExposedValue(lua_State* L) {
// set registry[&t] = { &t }
ls = L;
}
~LuaExposedValue() {
// remove &t from the table
}
}
Alternatively, just ban Lua from accessing it after the variable is gone and let the scripter worry about it.
Finally, you could just allocate everything that Lua can access using the Lua GC.
Disclaimer: I wrote the library I'm about to recommend
You might want to try using this LuaWrapper Library that sounds like it'll handle what you're trying to do. It's not even really a library, it's just a single header file.
You can use luaW_push<MyType>(L, myObj); to push your objects into Lua. Lua will not own the objects you create from C++ unless you run luaW_hold<MyType> on them. In other words, unless you tell Lua to, it will not garbage collect your object.
Conversely, you can use MyType.new() in your Lua code to create an object, which Lua does own. It will be garbage collected as you would expect. If you want to pass ownership to C++ you can call luaW_release<MyType> on your object.
There's also functions like luaW_to<MyType> and luaW_check<MyType> and to a limited degree it correctly supports inheritance from base types (though at the moment it only allows for single inheritance). I find that this greatly simplifies my own attempts at using C++ and Lua together because it make managing pointer ownership very straightforward.
There was an article i found long ago (i cant find it ATM) which states reasons why the new keyword in C++ is bad. I cant remember all of the reasons but the two i remember most is you must match new with delete, new[] with delete[] and you cannot use #define with new as you could with malloc.
I am designing a language so i like to ask how would you change the C++ language so new is more friendly. Feel free to state problems with new and articles. I wish i can find the article link but i remember it was long and was written by a professor at (IIRC) a known school.
I cannot see any reason to replace the new keyword with something else (and seems to be that C++ committee agree with me). It is clear and makes what it should. You could override operator new in your class, no need to use defines.
To eliminate new[]/delete[] problem you could use std::vector.
If you want to use smart pointer you could use it, but I want to control when smart pointer will be used. That's why I like how it works in C++ — high level behavior with ability to control low level details.
Problem match new, delete, new[], delete[]
Not really a big deal.
You should be wrapping memory allocation inside a class so this does not really affect normal users. A single obejct can be wrapped with a smart pointer. While an array can be represented by std::Vector<>
cannot use #define with new as you could with malloc.
The reason to mess with malloc like this was to introduce your own memory management layer between your app and the standard memory management layer. This is because in C you were not allowed to write your own version of malloc. In C++ it is quite legal to write your own version of the new which makes this trick unnecessary.
I'd give it the semantics of new in C# (more or less):
Allocates memory for the object.
Initializes the memory by setting the member variables to their default values (generally 0 for values, null for references).
Initializes the object's dynamic binding mechanism (vtables in C++, type def tables for managed VMs).
Calls the constructor, at which point virtual calls work as expected.
For a language without garbage collection (eww for a new language at this point), return a smart_ptr or similar from the call.
Also, make all objects either value types or reference types, so you don't have to keep an explicit smart_ptr. Only allow new to heap-allocate for reference types, and make sure it contains information to properly call the destructor. For value types, new calls the constructor on memory from the stack.
Use Garbage Collection so that you never need to match new with anything.
By using the STL container classes and the various boost:smart_ptrs, there's little need to ever explicitly call new or delete in your C++ code.
The few places you might need to call new (e.g, to initialize a smart pointer) use the Named Constructor Idiom to return your class type pointer wrapped in, e.g., a boost:shared_ptr.
But C++ and the STL work very very hard to allow you to treat most objects as value objects, so you can construct objects rather than pointers and just use them.
Given all this, there's little need to replace the new operator -- and doing so would introduce a host of problems, whether by requiring a garbage collector, or by reducing the fine low-level control C++ offers programmers.
If your new language is garbage collected, you can avoid the new keyword. Thats what Python did (and Lisp did almost 5 decades ago!). Also see an answer provided by Peter Norvig for a similar question here. (Is no "news" good news?)
Sometimes you want to replace the constructor with a factory. This is a well known refactoring. Replace Constructor With Factory Method. So perhaps this is what the article meant?
Incidentally you will often see straight calls to new being replaced with a Factory Method.
DI frameworks such as Unity take this concept to another level. As you can see in the following C# code, there is no "new" applied to create the IMyClass interface:
IUnityContainer myContainer = new UnityContainer();
myContainer.RegisterType<IMyClass, SomeClass>();
IMyClass thing = myContainer.Resolve<IMyClass>();
The reason that C++ has a separate new operator ( or C malloc ) is primarily so that objects can be created whose lifetimes exceed the scope of the function which creates them.
If you had tail call elimination and continuations, you wouldn't care - the objects could all be created on the stack and have unlimited extent - an object can exist until you call the continuation that corresponds to the object going out of scope and being destructed. You might then need something to garbage collect or otherwise compress the stack so it doesn't become full of no-longer required objects ( Chicken Scheme and TinyOS 2 are two different examples for giving the effect of dynamic memory without dynamic memory at either runtime or compile time; Chicken Scheme doesn't allow for RAII and TinyOS doesn't allow for true dynamic allocation ), though for a large amount of code such a scheme wouldn't be vastly different to RAII with the facility to chose to change the order the objects are destructed.