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

    CString assign causes exception (nRefs < 1)

    Hello,

    I have the following code:

    Code:
    item->nodeID = (*it_inst)->nodeID;
    where 'nodeID' in both cases are CStrings. The above assignment gives me an excetption in atlsimpstr.h:

    Code:
    	bool IsLocked() const throw()
    	{
    		return nRefs < 0;
    	}

    can you tell me why this is? When I do something like this:

    Code:
    LPCTSTR text = TEXT("123");
    CString ctext = text;
    the LPCTSTR content is copied to my CString. Isn't this the case when I assign another CString???

  2. #2
    Join Date
    Dec 2011
    Posts
    44

    Re: CString assign causes exception (nRefs < 1)

    It seems that 'item->nodeID' was not initialized yet. Adding

    Code:
    item->nodeID = "";
    solved the problem.

    BUT:

    After the assignment BOTH CString point to the same m_pszData?!? How can this be?

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

    "The contents of a CString object are copied when one CString object is assigned to another. Therefore, the two strings do not share a reference to the actual characters that make up the string."


    But that's not the case...

  3. #3
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,430

    Re: CString assign causes exception (nRefs < 1)

    Victor Nijegorodov

  4. #4
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: CString assign causes exception (nRefs < 1)

    Quote Originally Posted by chaos2oo2 View Post
    where 'nodeID' in both cases are CStrings. The above assignment gives me an excetption in atlsimpstr.h:

    Code:
    	bool IsLocked() const throw()
    	{
    		return nRefs < 0;
    	}
    This can only throw if you call it on uninitialized object.

    Quote Originally Posted by chaos2oo2
    It seems that 'item->nodeID' was not initialized yet.
    I don't know how you can have uninitialized CString. Or was it a pointer to CString?
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

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

    Re: CString assign causes exception (nRefs < 1)

    Quote Originally Posted by chaos2oo2 View Post
    Hello,

    I have the following code:

    Code:
    item->nodeID = (*it_inst)->nodeID;
    And how do we know if "item" is valid or if it_inst is valid? If those are not valid object, then using those objects in the way you're using them is also invalid.

    It doesn't matter if the member is a CString, an int, a double, or whatever you want to make it. Accessing members of an invalid object means the behaviour will be undefined, more than likely crash.
    When I do something like this:

    Code:
    LPCTSTR text = TEXT("123");
    CString ctext = text;
    the LPCTSTR content is copied to my CString. Isn't this the case when I assign another CString???
    Look at your second example, and look at your first example. There is a big difference:

    The first one uses objects that we have no idea what state they're in, while the second example uses no objects, therefore has to work correctly.

    If you want to write code that looks like your first example, and must work, this is closer:
    Code:
    #include <atlstr.h>
    
    struct SomeItem
    {
        CString nodeID;
    };
    
    void DoStuff(SomeItem* item, SomeItem* it_inst)
    {
        item->nodeID = it_inst->nodeID;
    }
    
    void foo()
    {
       SomeItem item1;
       SomeItem item2;
       item1.nodeID = _T("abc");
       item2.nodeID = _T("123");
       DoStuff(&item1, &item2);
    }
    
    int main()
    {
       foo();
    }
    This is a complete program. Run it and you should see that there is nothing wrong with CString.

    Regards,

    Paul McKenzie

  6. #6
    Join Date
    Dec 2011
    Posts
    44

    Re: CString assign causes exception (nRefs < 1)

    Quote Originally Posted by VladimirF View Post
    I don't know how you can have uninitialized CString. Or was it a pointer to CString?
    It wasn't a pointer. In my 'item.h" I just declared

    Code:
    CString nodeid;
    as public member but did not assign anything in the constructor. After adding

    Code:
    nodeid = "";
    to the constructor it worked.

  7. #7
    Join Date
    Dec 2011
    Posts
    44

    Re: CString assign causes exception (nRefs < 1)

    The complete code in snippets ^^ was the following:

    Code:
    	
    CRecordElement* instElement = new CRecordElement(description, instNodeID, INSTANCE);
    instElements->push_back(instElement);
    Code:
    CItem* item = new CItem((*it_inst)->description, DOCUMENT, folder);
    item->nodeID = (*it_inst)->nodeID;
    but I don't think this will help you to tell if it was valid or not...so far the debugger of VS2010 didn't report any 'bad ptr' or something

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

    Re: CString assign causes exception (nRefs < 1)

    Quote Originally Posted by chaos2oo2 View Post
    as public member but did not assign anything in the constructor. After adding

    Code:
    nodeid = "";
    to the constructor it worked.
    All you did was move the memory related bug to another part of your code -- you really didn't fix anything. When you declare a CString, the default constructor automatically makes the CString empty.

    Your program has corrupted memory somewhere and/or you're mismanaging pointers. Making innocuous and unnecessary changes as you've done, and then you see things "working" indicates that this is the problem. Who knows what other parts of your program will now mysteriously break now, and if not now, in the future. Usually, it's a customer who is using your software that discovers the bug that you think you've "fixed".

    I suggest you remove that code above, and really fix the problem by identifying why a CString that is (supposedly) properly constructed can all of a sudden, need to be set to empty.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; February 23rd, 2012 at 05:20 AM.

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

    Re: CString assign causes exception (nRefs < 1)

    Quote Originally Posted by chaos2oo2 View Post
    The complete code in snippets ^^ was the following:

    Code:
    	
    CRecordElement* instElement = new CRecordElement(description, instNodeID, INSTANCE);
    instElements->push_back(instElement);
    Code:
    CItem* item = new CItem((*it_inst)->description, DOCUMENT, folder);
    item->nodeID = (*it_inst)->nodeID;
    but I don't think this will help you to tell if it was valid or not...so far the debugger of VS2010 didn't report any 'bad ptr' or something
    The debugger doesn't report these things. It is your responsibility to handle memory related issues correctly, and if not, debug them.

    If it were as simple as having the debugger indicate you have an invalid pointer, then no one would use products such as BoundsChecker or Purify to find these problems.

    We can't help you if we don't have your entire program and duplicate the error. Just posting two perfectly valid calls to "new" doesn't tell us anything as to what you're doing with those pointers, when, where, and how those pointers are used, when they're deallocated, etc. That requires a runtime analysis of the entire codebase with whatever data is driving the program.

    But as my previous post pointed out, when you have bugs like this, you do not change code -- you debug the problem, see what's causing it, and actually fix it. By adding, removing, or changing code without doing these steps, you risk losing the chance to duplicate the problem, thereby making it difficult if not impossible to fix the underlying cause.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; February 23rd, 2012 at 05:18 AM.

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