How winrt::hstring manages memory and reference count while copying?

Shyam Butani 235 Reputation points
2024-10-16T05:42:52.1833333+00:00

Hello,

I want to understand how winrt::hstring manages memory when we copy hstring to another hstring.

    TextBlock tb;
    hstring label_copy;

    {
        hstring label = L"Sample text";   // Address: 0xA0 (assume)

        label_copy = label;            // Same Address: 0xA0

        tb.Text(label);
    }
    // label is now destroyed

    hstring temp = tb.Text();  // Same Address: 0xA0

Here, when we assign label to label_copy and tb.Text, the underlying string pointer remains the same. It means it's keeping the reference of the same hstring instead of copying the whole string data, right?

And even after scope of label is finished and it got destroyed, lable_copy and tb.Text still holds the same underlying pointer of the string.

So my doubt is, it is guaranteed that the memory allocated by label will not get de-allocated even after label is destroyed, because label_copy is holding the same memory address?

Universal Windows Platform (UWP)
0 comments No comments
{count} votes

Accepted answer
  1. Junjie Zhu - MSFT 18,501 Reputation points Microsoft Vendor
    2024-10-17T01:57:25.4166667+00:00

    Hello @Shyam Butani ,

    Welcome to Microsoft Q&A!

    It means it's keeping the reference of the same hstring instead of copying the whole string data, right?

    Yes, winrt::hstring just inlines this into its implementation and takes care of bumping the internal reference count when copies are made or allocating when fast-pass strings are copied. 

    So my doubt is, it is guaranteed that the memory allocated by label will not get de-allocated even after label is destroyed, because label_copy is holding the same memory address?

    Yes, because the reference count is greater than 0. If the reference count drops to zero, then the string is destroyed.

    For detail information please refer to Raymond’s complete guide to HSTRING semantics.

    Thank you.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Viorel 118K Reputation points
    2024-10-16T16:37:47.8933333+00:00

    During debugging, the behaviour can be checked by stepping with <F11>, or selecting hstring and pressing <F12>. I.e. the source of hstring is available.

    Currently, it seems that the contents of the string is allocated on process heap and is preceded by an atomic reference count. For example, to view the count of label, enter an expression like this in Watch window:

    (winrt::impl::shared_hstring_header*)label.m_handle.get()

    The count will be 2 after label_copy = label. The contents of the string is not duplicated. (The memory block on the heap is shared, and sizeof(hstring) corresponds to a pointer). Destruction of label and label_copy variables, or calling clear(), does not affect the text of tb. The memory is released when no references exist (when count becomes zero).


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.