CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15
  1. #1
    Join Date
    Dec 2011
    Posts
    44

    Strange CString behaviour??

    Hello,

    I have the following code segments:


    Code:
    CString fooA = TEXT("");
    CString fooB = TEXT("");
    and then I have a class member/method like this:

    Code:
    CString* pStr; // this is a pointer to my CString;
    
    void Constructor(CString* str){ // Constructor of my class
        this->pStr = str;
    }
    
    void doSomething(){ //Member method of my class
       *(this->pStr) = TEXT("FOO");
    }

    When I pass '&fooA' to the constructor of my class and execute 'doSomething' somewhen, the content of 'fooB' changes? How can this be? Every variable in my whole program which has TEXT("") assigned to it changes it's content to "FOO" - did I change TEXT("")'s content??? please help


    kind regards,
    Michael
    Last edited by chaos2oo2; March 2nd, 2012 at 07:52 AM.

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Strange CString behaviour??

    Quote Originally Posted by chaos2oo2 View Post
    Hello,

    I have the following code segments:


    Code:
    CString fooA = TEXT("");
    CString fooB = TEXT("");
    and then I have a class member/method like this:

    Code:
    CString* pStr; // this is a pointer to my CString;
    
    void Constructor(CString* str){ // Constructor of my class
        this->pStr = str;
    }
    
    void doSomething(){ //Member method of my class
       *(this->pStr) = TEXT("FOO");
    }

    When I pass '&fooA' to the constructor of my class and execute 'doSomething' somewhen, the content of 'fooB' changes? How can this be?
    Instead of bits and pieces of some code, why not post a small, tiny, but complete program that demonstrates this error?

    Regards,

    Paul McKenzie

  3. #3
    Join Date
    Dec 2011
    Posts
    44

    Re: Strange CString behaviour??

    I figured out that this here messed up my programm:

    Code:
    void CNewDocumentDialog::okClicked()
    {
    
    	if(m_spsDropDown.GetCurSel() != CB_ERR){
    
    		// prepare description for check
    		CString description;
    		m_descriptionEdit.GetWindowTextW((LPTSTR)(LPCTSTR)description, m_descriptionEdit.GetWindowTextLengthW() + 1);
    
    		description.Trim();
    
    		if(description.Compare(TEXT("")) != 0){
    			
    			CString spsId;
    			m_spsDropDown.GetLBText(m_spsDropDown.GetCurSel(), spsId);
    
    			SPSMap::iterator it_spsMap = this->m_spsMap->find(spsId);
    
    			if(it_spsMap == m_spsMap->end()){
    				C4PEPUtils::DisplayMessage(TEXT("An error occured!"), MB_ICONERROR | MB_OK, this->m_hWnd);
    				CDialogEx::OnCancel();
    				return;
    			}
    
    			(*this->m_selIndex) = it_spsMap->second;
    
    			(*this->m_description) = description;
    
    			CDialogEx::OnOK();
    
    		} else C4PEPUtils::DisplayMessage(TEXT("Please enter a description!"), MB_ICONASTERISK | MB_OK, this->m_hWnd);
    
    	}else C4PEPUtils::DisplayMessage(TEXT("Please select some SPS!"), MB_ICONASTERISK | MB_OK, this->m_hWnd);
    
    }
    and this was the problem:
    Code:
    CString description;    // points internal to TEXT("")
    m_descriptionEdit.GetWindowTextW((LPTSTR)(LPCTSTR)description, m_descriptionEdit.GetWindowTextLengthW() + 1); // change content of memory address for TEXT("")
    this seems to change the content of TEXT(""). Afterwards it seems to make sense...I took the char array behind description which initially points to TEXT("") and make it's content changeable, so I did change TEXT("").
    Last edited by chaos2oo2; March 2nd, 2012 at 08:10 AM.

  4. #4
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,637

    Re: Strange CString behaviour??

    Best guess is fooA goes out of scope so you're storing an invalid pointer, but without more code, there's no telling.

  5. #5
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Strange CString behaviour??

    Code:
    #include "stdafx.h"
    
    class SomeClass
    {
        CString *pStr;
    
        public:
        SomeClass(CString* str)
        {
            pStr = str;
        }
    
        void doSomething()
        { 
            *pStr = TEXT("FOO");
        }
    };
    
    int main()
    {
        CString fooA = TEXT("");
        CString fooB = TEXT("");
        SomeClass sc(&fooA);
        sc.doSomething();
    }
    The following program shows that only fooA is changed after doSomething is called, just as expected.

    So add to the program above the code that duplicates what you're seeing. If you can't, then the bug isn't with CString, it's with the rest of your program.

    Regards,

    Paul McKenzie

  6. #6
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,637

    Re: Strange CString behaviour??

    Quote Originally Posted by Paul McKenzie View Post
    the bug isn't with CString, it's with the rest of your program.

    Regards,

    Paul McKenzie
    That pretty much goes without saying.

  7. #7
    Join Date
    Dec 2011
    Posts
    44

    Re: Strange CString behaviour??

    Quote Originally Posted by Paul McKenzie View Post
    Code:
    #include "stdafx.h"
    
    class SomeClass
    {
        CString *pStr;
    
        public:
        SomeClass(CString* str)
        {
            pStr = str;
        }
    
        void doSomething()
        { 
            *pStr = TEXT("FOO");
        }
    };
    
    int main()
    {
        CString fooA = TEXT("");
        CString fooB = TEXT("");
        SomeClass sc(&fooA);
        sc.doSomething();
    }
    The following program shows that only fooA is changed after doSomething is called, just as expected.

    So add to the program above the code that duplicates what you're seeing. If you can't, then the bug isn't with CString, it's with the rest of your program.

    Regards,

    Paul McKenzie


    Agree...the problem was this:

    Code:
    CString description;    // points internal to TEXT("")
    m_descriptionEdit.GetWindowTextW((LPTSTR)(LPCTSTR)description, m_descriptionEdit.GetWindowTextLengthW() + 1); // change content of memory address for TEXT("")

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Strange CString behaviour??

    Quote Originally Posted by chaos2oo2 View Post
    I figured out that this here messed up my programm:
    So do you think a LPTSTR cast changes a CString into a writeable CString? A CString is not writeable unless you explicitly call the functions to make it writeable.

    http://msdn.microsoft.com/en-us/library/awkwbzyc.aspx

    See "Modifying CString contents Directly" in the above link.

    In general, if a function wants to change the value of a passed-in parameter, unless it is documented that casting will work, it is undefined behaviour to fake out C++ by just casting a const or non-writeable type to a writeable type. Maybe it will work, or maybe it will fail miserably.

    Regards,

    Paul McKenzie

  9. #9
    Join Date
    Dec 2011
    Posts
    44

    Re: Strange CString behaviour??

    Quote Originally Posted by Paul McKenzie View Post
    So do you think a LPTSTR cast changes a CString into a writeable CString? A CString is not writeable unless you explicitly call the functions to make it writeable.

    http://msdn.microsoft.com/en-us/library/awkwbzyc.aspx

    See "Modifying CString contents Directly" in the above link.

    In general, if a function wants to change the value of a passed-in parameter, unless it is documented that casting will work, it is undefined behaviour to fake out C++ by just casting a const or non-writeable type to a writeable type. Maybe it will work, or maybe it will fail miserably.

    Regards,

    Paul McKenzie
    so you don't think this cast above was the source of my problem? Or do you think it was?

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Strange CString behaviour??

    Quote Originally Posted by chaos2oo2 View Post
    Agree...the problem was this:

    Code:
    CString description;    // points internal to TEXT("")
    m_descriptionEdit.GetWindowTextW((LPTSTR)(LPCTSTR)description, m_descriptionEdit.GetWindowTextLengthW() + 1); // change content of memory address for TEXT("")
    So let's see what happens with a simpler program:
    Code:
    #include "stdafx.h"
    
    class SomeClass
    {
        CString *pStr;
    
        public:
        SomeClass(CString* str)
        {
            pStr = str;
        }
    
        void doSomething()
        { 
            *pStr = TEXT("FOO");
        }
    };
    
    void SomeWindowsFunc(TCHAR* ptr)
    {
        ptr[0] = _T('x');
    }
    
    int main()
    {
        CString fooA = TEXT("");
        CString fooB = TEXT("");
    
        SomeWindowsFunc((LPTSTR)(LPCTSTR)fooA);
    
        SomeClass sc(&fooA);
        sc.doSomething();
    }
    After the call to SomeWindowsFunc, I've just screwed up the internal reference counting mechanism of CString by circumventing the check to see if the two CStrings fooA and fooB have changed.

    The CString class is reference counted. The fooA and fooB are internally pointing to the same memory block since they are initialized to equal values. The CString class makes checks whenever a CString is changed through the public interface of CString to update the reference counts. Since SomeWindowsFunc totally bypasses this, the reference counting scheme is now corrupted.

    Regards,

    Paul McKenzie

  11. #11
    Join Date
    Dec 2011
    Posts
    44

    Re: Strange CString behaviour??

    and after SomeWindowsFunc was called 'fooB'must have been changed too, right?

  12. #12
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Strange CString behaviour??

    Quote Originally Posted by chaos2oo2 View Post
    so you don't think this cast above was the source of my problem? Or do you think it was?
    Did you read my post carefully? I even showed you the link to how to make CStrings writeable.

    You are attempting to make CString writeable by casting. You don't make objects writeable by just casting. See my simple program showing you what happens when you do so.

    Regards,

    Paul McKenzie

  13. #13
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Strange CString behaviour??

    Quote Originally Posted by chaos2oo2 View Post
    and after SomeWindowsFunc was called 'fooB'must have been changed too, right?
    Yes. So the issue is again, you can't make things writeable by casting.

    I'm trying to get you to understand that the issue is not only with CString, but any C++ type that is either const or not documented to be writeable by just casting.

    If a function's parameter is non-const, then casting a const type to non-const as you did will not work, or at the least, is not guaranteed to work. You tried to cast an LPCTSTR into a LPTSTR (const to non-const). What happened? All sorts of funny stuff.

    Regards,

    Paul McKenzie

  14. #14
    Join Date
    Dec 2011
    Posts
    44

    Re: Strange CString behaviour??

    Yes I did, but maybe missed your point of view somehow...maybe my english is not good enough. I know now that I can't just make it writeable by casting my CString.

  15. #15
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,637

    Re: Strange CString behaviour??

    GetWindowText takes a CString& as an argument anyway. Why not just pass the CString directly as an argument. All you need is
    Code:
    CString description;    // points internal to TEXT("")
    m_descriptionEdit.GetWindowTextW(description);

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured