Question about CWnd::GetWindowString

2009-05-30
2013-05-28
  • Todor Totev
    Todor Totev
    2009-05-30

    In this function you get the length of the text but do not use it to allocate the memory buffer. I cannot understand the reason behind this code. Shouldn't the memory allocation read

    TCHAR szString[max(MAX_STRING_SIZE +1, nLength)];

    or simply

    TCHAR szString[nLength+1];

     
    • David
      David
      2009-05-31

      The following is not a valid C++ statement:
        TCHAR szString[nLength+1];

      What would be valid is something like this:
        TCHAR* pszString = new TCHAR[nLength];
        // Do stuff with pszString here
        delete []pszString;

      It would be perfectly valid to use 'new' to allocate this memory, but I tend to avoid using 'new' to allocate tiny amounts of of memory on the heap in situations where it might get allocated often. It serves little purpose and risks fragmenting the heap memory. These sort of memory allocations might as well be on the stack.

      There are other (albeit slight) advantages to allocating memory on the stack:
      - memory allocation in the heap is slower than on the stack
      - memory allocations on the stack can't fail, whereas 'new' can throw an exception.

      David

        

       
      • Todor Totev
        Todor Totev
        2009-05-31

        Sorry, I meant using _alloca() or friends.

        But you truncate the text without any indication to the user of this function that this happened. There is no way to use this function without risking truncating the user input.
        I am not sure that speed argument trumps the correctness one. If you care for performance so much, why don't do (pseudocode)

        if (nLength < MAX_STRING_SIZE)
          _alloca(nLength)
        else
        new TCHAR[nLength];

        Also:
        > memory allocations on the stack can't fail, whereas 'new' can throw an exception.

        The default configuration of the MS linker reserves 4 MiB of stack and the heap is limited by 2 GiB (unless LARGE_ADDRESS_AWARE bit in the PE file header is set). The stack is much scarser resource. Also, when stack is exausted, a SEH exception is generated and I am not even sure it can be caught on the same thread. And, given the fact that simple "throw" statement for MS compilers require 12KiB of stack for execution, I'm not sure that installing a SEH translator handler to convert it to a c++ exception is doable. Managing stack exaustion is a nightmare compared to handling of heap exaustion. Because of the specifics of the code base we develop, I've seen much more stack overflows that heap exaustions so I prefer the later.

         
    • David
      David
      2009-06-01

      You're correct. Text might get truncated, so I'll make the appropriate change to the function.

      David