Thread: Cannot convert two digit-long integer to std::string

  1. #16
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by laimaretto View Post
    @adeyblue/bithub:

    Sorry if this question is somehow silly or generic but: how do you know or what did you do to see/test/findout that the functions are leaking memory? How do I prevent this memory leak?
    Because you obtain memory, and don't give it back. malloc gets you memory -- to give it back you need free. I probably should have put that in my function but I wasn't sure it would actually work.

    Your first one is perhaps the more insidious, since "return buffer" makes you think that you are lobbing that memory back to the person who called you (which makes it their problem to free it, not yours). However, since you are returning a std::string, that's not true -- the string is constructed from that buffer and the string is returned -- the buffer is no longer needed. In order to deal with this, you should explicitly construct a string object, then free the memory, then return the new string object (don't worry, it has it's own copy of the data, so you giving the original copy away won't hurt).

  2. #17
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    By using std::[w]string and std::vector, memory management is handled for you.
    The second parameter is optional. If a second parameter is not given, then CP_ACP is assumed.
    Code:
    BSTR b1, b2;
    ...
    std::string s = wstr_to_str(b1);
    ...
    b2 = SysAllocString(str_to_wstr(s).c_str());
    Changing it to "str_to_BSTR()" and "BSTR_to_str()" wouldn't be hard either once you understand what the current code is doing. Or just don't do conversions and work with std::wstring's directly.

    gg

  3. #18
    Registered User
    Join Date
    Dec 2010
    Location
    Cordoba, Argentina
    Posts
    27
    Ok, so here are the functions freeing (and deleting) the memory used:

    string2bstr:
    Code:
    BSTR string2bstr(string input_string)
    {
        // MultyBytetoWideChar converts ANSI strings to UNICODE
        // int len2 is the required size in wide chars
        // it includes the NULL char at the end. So it's "len"+1
        // The codepage CP_ACP -AnsiCodePage- is used by Windows (Excel)
        //  When using 'As string' in VBA causes autmatically UNICODE->ANSI conversion.
        int len2 = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, input_string.c_str(),-1, NULL, 0);
    
        // malloc returns a pointer to the begining of the buffer
        // buffer size in memory is (len2*sizeof(*buffer))
        // 5th parameter of MultiByteToWideChar is LPWSTR
        // 1st parameter= CP_ACP = ANSI Code Page
        LPWSTR buffer = (LPWSTR)malloc(len2 * sizeof(*buffer));
        MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, input_string.c_str(), -1, buffer,len2);
    
        // SysAllocString allocates a new string and copies the passed string into it.
        // The input_parameter must be a Unicode string in 32-bit applications,
        // and an ANSI string in 16-bit applications. The input parameter may be NULL.
        BSTR out_buffer;
        out_buffer = SysAllocString(buffer);
    
        // since we allocated memory to accomodate the string
        // --(LPWSTR)malloc(len2 * sizeof(*buffer)))--
        // we must then delete it. To do so, we created BSTR out_buffer and
        // copied into it the information within 'buffer'.
        free(buffer);
        return out_buffer;
    }

    bstr2string:
    Code:
    string bstr2string(BSTR input_string)
    {
        DWORD len, bstrLength;
        size_t result;
    
        // +1 for NULL teminator
        // bstrLength is measured in Chars
        bstrLength = SysStringLen(input_string)+1;
        // len is measured in Bytes
        len = WideCharToMultiByte(CP_ACP, 0, input_string, bstrLength, 0, 0, 0, 0);
    
        if (len>0)
        {
            char *buffer = new char[len];
            result = WideCharToMultiByte(CP_ACP, 0, input_string, bstrLength,buffer,len, 0, 0);
    
            // since we allocated memory to accomodate the string --new char[len])--
            // we must then delete it. To do so, we create std::string out_buffer and
            // copy into it the information within 'buffer'.
            string out_buffer = buffer;
            delete buffer;
            return out_buffer;
        }
        else
        {
            return ("Error");
        }
    
    }
    @Codeplug:

    I'll study your code (I need to deepen my knowledge regarding C++ data types in order to fully understand the difference between std::string and std::wstring before moving on). After that I'll promise I'll try to improve my functions with your suggestions ...

    Thanks to everyone ... again, any improvement is very welcome ...

    Rgds!

    Lucas

  4. #19
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    - No error checking on MultiByteToWideChar, WideCharToMultiByte, malloc, SysAllocString, and new (if it doesn't throw).
    - Use new/delete in C++ code (malloc/free in C)
    - Don't use MB_PRECOMPOSED
    https://blogs.msdn.com/b/michkap/arc...7/9644420.aspx
    https://blogs.msdn.com/b/michkap/arc...6/3558548.aspx

    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Error in Exceptions.h file during build of QuickFix library
    By arupsarkar in forum C++ Programming
    Replies: 3
    Last Post: 07-16-2010, 10:30 AM
  2. Need help with Realloc()
    By krazyxazn in forum C Programming
    Replies: 10
    Last Post: 01-27-2010, 10:05 PM
  3. Inserting a swf file in a windows application
    By face_master in forum Windows Programming
    Replies: 12
    Last Post: 05-03-2009, 11:29 AM
  4. Link List math
    By t014y in forum C Programming
    Replies: 17
    Last Post: 02-20-2009, 06:55 PM
  5. need help
    By emperor in forum C Programming
    Replies: 1
    Last Post: 03-04-2002, 12:26 PM