A little while back, I posted
my complete guide to HSTRING semantics
(a rip-off of
Eric's complete guide to BSTR semantics).
A discussion of security descriptor lifetime
somehow triggered the question
"When can you free the memory backing the
you created with
You can free the memory backing the
after you destroy the
and since this is a fast-pass string,
you destroy the
HSTRING by simply abandoning it.
Therefore, you can free the memory when you know that nobody
should have a copy of the fast-pass
HSTRING handle any more.
(For the purpose of terminology,
I'm going to say that you have a "copy" of an
if you merely copied the
HSTRING copy = hstr;
On the other hand, I'm going to say that you have a
"duplicate" of an
HSTRING if you passed it to
Okay, so how do you know that
has a copy of the fast-pass
HSTRING handle any more?
Recall the rules for
If a function is passed
HSTRING and it wants to save the
HSTRING for future use,
it must use
WindowsDuplicateString to increment
the reference count on the string (and possibly convert it from
fast-pass to standard).
if you pass the
HSTRING to another function,
you know that there are no copies of that
when the function returns,
because creating a copy is not allowed.
The only place where a literal copy of the
is allowed is in the function that created it,
and therefore you know when there are no more copies of the
HSTRING handle because all of the copies belong to you.
The question sort of acknowledges this rule, but notes, "All it takes is one bug somewhere in all of WinRT where someone forgets to duplicate a input string if they need said string later after the function has returned."
But it's true of C-style string pointers, too!
If you pass a C-style string to another function,
and that other function wants to retain the string,
it's going to need to call
strdup or some
other string duplication function so it can have its own
private copy of the string.
The value received as a function parameter is not
valid once the function returns;
if you need to use it after the function returns,
you need to duplicate the string.
Similarly, if you receive a COM interface pointer,
and you want to continue using it after the function returns,
you need to call
IUnknown:: to increase
the reference count on the interface, corresponding to the
copy of the pointer you retained.
When you're done with the pointer, you call
In both of these cases, you are relying on people writing code to respect these rules. All it takes is one bug somewhere in all of C where someone forgets to duplicate a input string if they need said string later after the function has returned.
Somehow, we've managed to survive working with C-style strings and with COM interface pointers with these rules. Maybe it's with the help of things like smart pointers, or maybe it's just through good discipline. Whatever the reason, keep up the good work.
One of the rules for fast-pass strings is that you cannot
change the contents of the string as long as the
is still in use.
One commenter interpreted this to mean that
string references aren't thread-safe.
Rather, the statement is a
direct reflection of the fact that an
If you changed the contents of the buffer that backs the
then you break the immutability rule.
Thread safety is not at issue here.
You can use a fast-pass string from any thread you like,
as long as you stop using it before your function returns.
(This means that your function cannot return until
the other thread has definitely finished with the fast-pass
In practice, this is not commonly done; instead, the function
WindowsDuplicateString to create a
HSTRING and passes that
to the other thread,
which can then
when it is done.)