Loading ...
Sorry, an error occurred while loading the content.

RE: [wtl] Cstring question Again

Expand Messages
  • tarun.kanal@wipro.com
    Hi All I ve come across a piece of code. This is defined in AtlBase.h line number 3977 BSTR Detach() { BSTR s = m_str; m_str = NULL; return s; } Now in this
    Message 1 of 10 , Sep 2, 2004
    • 0 Attachment
      Hi All

      I've come across a piece of code.

      This is defined in AtlBase.h line number 3977

      BSTR Detach()
      {
      BSTR s = m_str;
      m_str = NULL;
      return s;
      }

      Now in this method m_str is being made NULL without being released.
      Is this correct? Its giving me a memory leak out here.

      My Code is as follows

      CComBSTR bstrTemp = T2W(szData);
      *bstrBuffer = bstrTemp.Detach(); //this is giving a memory leak

      Any pointers how to tackle this or is my approach wrong??

      Regards
      Tarun
    • Pablo Aliskevicius
      ... Yes, this is correct. The alternative could be: BSTR Detach() { BSTR garbage = m_str; ... m_str = NULL; return garbage; } See what I mean? This function
      Message 2 of 10 , Sep 2, 2004
      • 0 Attachment
        <tarun.kanal@...> writes:

        >
        > Hi All
        >
        > I've come across a piece of code.
        >
        > This is defined in AtlBase.h line number 3977
        >
        > BSTR Detach()
        > {
        > BSTR s = m_str;
        > m_str = NULL;
        > return s;
        > }
        >
        > Now in this method m_str is being made NULL without being released.
        > Is this correct? Its giving me a memory leak out here.
        >

        Yes, this is correct. The alternative could be:

        BSTR Detach()
        {
        BSTR garbage = m_str;
        ::SysFreeString(m_str); // This line trashes 'garbage'
        m_str = NULL;
        return garbage;
        }

        See what I mean? This function HAS to return a VALID BSTR.

        > My Code is as follows
        >
        > CComBSTR bstrTemp = T2W(szData);
        > *bstrBuffer = bstrTemp.Detach(); //this is giving a memory leak
        >
        > Any pointers how to tackle this or is my approach wrong??
        >

        Option 1:


        CComBSTR bstrTemp = T2W(szData);
        *bstrBuffer = bstrTemp.Detach(); //this is giving a memory leak

        // After returning from wherever the former happened...
        DoStuffWith(bstrBuffer);
        DoMoreStuffWith(bstrBuffer);

        // And, finally.
        ::SysFreeString(*bstrBuffer);

        Option 2:

        {
        CComBSTR bstrTemp = T2W(szData);
        DoStuffWith(bstrTemp);
        DoMoreStuffWith(bstrTemp);
        // bstrTemp's destructor cleans up very nicely.
        }


        See also:

        http://www.devguy.com/fp/Tips/COM/bstr.htm

        Best wishes,

        Pablo.

        > Regards
        > Tarun
        >
        >
        >
        > Yahoo! Groups Links
        >
        >
        >
        >
        >
      • pablo_alch
        ... Yes, this is correct. Consider the alternative: BSTR Detach() { BSTR garbage = m_str; ... m_str = NULL; return garbage; } This function is supposed to
        Message 3 of 10 , Sep 2, 2004
        • 0 Attachment
          --- In wtl@yahoogroups.com, <tarun.kanal@w...> wrote:
          >
          > Hi All
          >
          > I've come across a piece of code.
          >
          > This is defined in AtlBase.h line number 3977
          >
          > BSTR Detach()
          > {
          > BSTR s = m_str;
          > m_str = NULL;
          > return s;
          > }
          >
          > Now in this method m_str is being made NULL without being released.
          > Is this correct? Its giving me a memory leak out here.
          >

          Yes, this is correct. Consider the alternative:

          BSTR Detach()
          {
          BSTR garbage = m_str;
          ::SysFreeString(m_str); //Effectively trashing garbage
          m_str = NULL;
          return garbage;
          }

          This function is supposed to return a valid BSTR. You're supposed to
          release that BSTR later.

          > My Code is as follows
          >
          > CComBSTR bstrTemp = T2W(szData);
          > *bstrBuffer = bstrTemp.Detach(); //this is giving a memory leak
          >

          Alternative 1:

          CComBSTR bstrTemp = T2W(szData);
          *bstrBuffer = bstrTemp.Detach(); //this is giving a memory leak

          // Later
          DoStuffWith(bstrBuffer);
          DoMoreStuffWith(bstrBuffer);

          // Finally
          ::SysFreeString(bstrBuffer);

          Alternative 2:

          {
          CComBSTR bstrTemp = T2W(szData);

          DoStuffWith(bstrTemp);
          DoMoreStuffWith(bstrTemp);

          // Let the destructor clean up.
          }


          See also:

          http://www.devguy.com/fp/Tips/COM/bstr.htm

          Best wishes,

          Pablo.




          > Any pointers how to tackle this or is my approach wrong??
          >
          > Regards
          > Tarun
        • Kim Gräsman
          Hi Tarun, ... That s what Detach() does. It transfers ownership of the string to the caller. ... What do you do with *bstrBuffer afterwards? Kim
          Message 4 of 10 , Sep 2, 2004
          • 0 Attachment
            Hi Tarun,

            > Now in this method m_str is being made NULL without being released.
            > Is this correct? Its giving me a memory leak out here.

            That's what Detach() does. It transfers ownership of the string to the
            caller.

            > CComBSTR bstrTemp = T2W(szData);
            > *bstrBuffer = bstrTemp.Detach(); //this is giving a memory leak

            What do you do with *bstrBuffer afterwards?

            Kim
          • tarun.kanal@wipro.com
            Hi Its an out parameter for a function. I m loading string from resource and passing it back. Regards Tarun ... From: Kim Gräsman [mailto:kim@mvps.org] Sent:
            Message 5 of 10 , Sep 2, 2004
            • 0 Attachment
              Hi

              Its an out parameter for a function.
              I'm loading string from resource and passing it back.

              Regards
              Tarun

              -----Original Message-----
              From: Kim Gräsman [mailto:kim@...]
              Sent: Thursday, September 02, 2004 1:10 PM
              To: wtl@yahoogroups.com
              Subject: Re: [wtl] Cstring question Again


              Hi Tarun,

              > Now in this method m_str is being made NULL without being released. > Is this correct? Its giving me a memory leak out here.

              That's what Detach() does. It transfers ownership of the string to the
              caller.

              > CComBSTR bstrTemp = T2W(szData);
              > *bstrBuffer = bstrTemp.Detach(); //this is giving a memory leak

              What do you do with *bstrBuffer afterwards?

              Kim




              Yahoo! Groups Links
            • Edwards, John
              There is nothing wrong with the code in Detach(), it is simply handing over ownership of the BSTR to whatever is calling it. The calling method now has the
              Message 6 of 10 , Sep 2, 2004
              • 0 Attachment
                There is nothing wrong with the code in Detach(), it is simply handing over
                ownership of the BSTR to whatever is calling it. The calling method now
                has the duty to deal locate the BSTR when it is finished with it by calling
                ::SysFreeString(yourBSTR). So your memory leak is probably because you are
                not freeing the BSTR that you took ownership of when you called Detach().

                -----Original Message-----
                From: tarun.kanal@... [mailto:tarun.kanal@...]
                Sent: 02 September 2004 08:08
                To: wtl@yahoogroups.com
                Subject: RE: [wtl] Cstring question Again



                Hi All

                I've come across a piece of code.

                This is defined in AtlBase.h line number 3977

                BSTR Detach()
                {
                BSTR s = m_str;
                m_str = NULL;
                return s;
                }

                Now in this method m_str is being made NULL without being released.
                Is this correct? Its giving me a memory leak out here.

                My Code is as follows

                CComBSTR bstrTemp = T2W(szData);
                *bstrBuffer = bstrTemp.Detach(); //this is giving a memory leak

                Any pointers how to tackle this or is my approach wrong??

                Regards
                Tarun




                Yahoo! Groups Links
              • Johann Gerell
                Thats what Detach() should do. Releasing the buffer is made by Empty(). Why don t you assign immediately? As in *bstrBuffer = T2W(szData); /Johann ... From:
                Message 7 of 10 , Sep 2, 2004
                • 0 Attachment
                  Thats what Detach() should do. Releasing the buffer is made by Empty().

                  Why don't you assign immediately? As in

                  *bstrBuffer = T2W(szData);

                  /Johann


                  -----Original Message-----
                  From: tarun.kanal@... [mailto:tarun.kanal@...]
                  Sent: den 2 september 2004 09:08
                  To: wtl@yahoogroups.com
                  Subject: RE: [wtl] Cstring question Again


                  Hi All

                  I've come across a piece of code.

                  This is defined in AtlBase.h line number 3977

                  BSTR Detach()
                  {
                  BSTR s = m_str;
                  m_str = NULL;
                  return s;
                  }

                  Now in this method m_str is being made NULL without being released.
                  Is this correct? Its giving me a memory leak out here.

                  My Code is as follows

                  CComBSTR bstrTemp = T2W(szData);
                  *bstrBuffer = bstrTemp.Detach(); //this is giving a memory leak

                  Any pointers how to tackle this or is my approach wrong??

                  Regards
                  Tarun


                  ------------------------ Yahoo! Groups Sponsor --------------------~--> Make
                  a clean sweep of pop-up ads. Yahoo! Companion Toolbar.
                  Now with Pop-Up Blocker. Get it for free!
                  http://us.click.yahoo.com/L5YrjA/eSIIAA/yQLSAA/saFolB/TM
                  --------------------------------------------------------------------~->


                  Yahoo! Groups Links
                • Ryan Ginstrom
                  ... Then how about: CComBSTR tmpRes ; tmpRes.LoadString( IDS_STRING_RES ) ; tmpRes.CopyTo( &OutStr ) ; Regards, Ryan ... Ryan Ginstrom ryang@gol.com
                  Message 8 of 10 , Sep 2, 2004
                  • 0 Attachment
                    tarun.kanal@... wrote:
                    > Hi
                    >
                    > Its an out parameter for a function.
                    > I'm loading string from resource and passing it back.

                    Then how about:

                    CComBSTR tmpRes ;
                    tmpRes.LoadString( IDS_STRING_RES ) ;
                    tmpRes.CopyTo( &OutStr ) ;

                    Regards,
                    Ryan

                    ---
                    Ryan Ginstrom
                    ryang@...
                  • Ryan Ginstrom
                    ... Incidentally, the following is the most efficient way *I* know how to do it (lifted substantially from MSDN)... UINT block = (uid 4) + 1; // Compute
                    Message 9 of 10 , Sep 2, 2004
                    • 0 Attachment
                      tarun.kanal@... wrote:
                      > Its an out parameter for a function.
                      > I'm loading string from resource and passing it back.

                      Incidentally, the following is the most efficient way *I* know how to do it
                      (lifted substantially from MSDN)...

                      UINT block = (uid >> 4) + 1; // Compute block number. -- uid is
                      resource id.
                      UINT num = uid & 0xf; // Compute offset into block.

                      HRSRC hRC = FindResourceEx( _Module.GetResourceInstance(),
                      RT_STRING,
                      MAKEINTRESOURCE(block),
                      MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));

                      if ( hRC == NULL )
                      {
                      OutString = NULL ;
                      return E_FAIL ;
                      }

                      HGLOBAL hgl = LoadResource(_Module.GetResourceInstance(), hRC);

                      if ( hgl == NULL )
                      {
                      OutString = NULL ;
                      return E_FAIL ;
                      }

                      LPWSTR str = (LPWSTR)LockResource(hgl);

                      if ( str == NULL )
                      {
                      OutString = NULL ;
                      return E_FAIL ;
                      }

                      for ( UINT i = 0; i < num; i++)
                      {
                      str += *str + 1;
                      }

                      *OutString = ::SysAllocStringLen( str+1, *str ) ;

                      Probably better to use CComBSTR unless you are filling a *lot* of these guys
                      -- or the round-trip through ASCII is going to mangle your strings.

                      Regards,
                      Ryan

                      ---
                      Ryan Ginstrom
                      ryang@...
                    • Igor Tandetnik
                      Johann Gerell wrote in message news:20040902080559.21F09FBA3D@csmtp.b-one.net ... T2W does _not_ produce a valid BSTR. It allocates a
                      Message 10 of 10 , Sep 2, 2004
                      • 0 Attachment
                        "Johann Gerell" <johann@...> wrote
                        in message news:20040902080559.21F09FBA3D@csmtp.b-one.net
                        > Thats what Detach() should do. Releasing the buffer is made by
                        > Empty().
                        >
                        > Why don't you assign immediately? As in
                        >
                        > *bstrBuffer = T2W(szData);

                        T2W does _not_ produce a valid BSTR. It allocates a temporary buffer on
                        the stack, which is released when the function returns. Your code will
                        result in a dangling pointer. But see T2BSTR - this one does allocate a
                        BSTR with SysAllocString. I personally prefer

                        *bstrBuffer = CComBSTR(szData).Detach();

                        CComBSTR has constructors taking Unicode and Ansi strings.
                        --
                        With best wishes,
                        Igor Tandetnik

                        "For every complex problem, there is a solution that is simple, neat,
                        and wrong." H.L. Mencken
                      Your message has been successfully submitted and would be delivered to recipients shortly.