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

    Unhappy Problem with CString in struct (C++)

    Hi,

    I have a question - the following pieces of code keep generating a debug error (in VC++)

    file1.hpp
    -----------
    struct A
    {
    CString m_name;
    enum_type m_value;
    };
    // end file1.hpp

    file1.cpp
    -----------
    #include "file1.hpp"
    ...
    static A aArray [ 100 ];
    ...
    bool someFunction ( int pos, CString name, enum_type value )
    {
    aArray[pos].m_name = name // <-- causes the assertion error
    aArray[pos].m_value = value
    }
    ...
    void main()
    {
    someFunction(0,"lalala",ENUM_VALUE);
    }
    // end file1.cpp

    A watch on the 'aArray' indicates that the CString members can't be viewed, presumably because the CString has not been initialized. About the assertion error, it comes during a GetData call, where it finds that the m_pchData variable is null.

    Do I need to override the copy constructor for the struct?
    Do I need to perform some initialization?
    Have I written absolutely horrible code?

    Sorry for the newbie question - any help would be greated appreciated!

    -cb

  2. #2
    Join Date
    Oct 2001
    Location
    Dublin, Eire
    Posts
    880
    One question, is your variable PUBLIC.

    if not, it might be the trouble.
    Elrond
    A chess genius is a human being who focuses vast, little-understood mental gifts and labors on an ultimately trivial human enterprise.
    -- George Steiner

  3. #3
    Join Date
    Oct 2001
    Location
    Dublin, Eire
    Posts
    880
    Do you check your index (pos). Are you sure you don't go after you array allocated memory?
    Elrond
    A chess genius is a human being who focuses vast, little-understood mental gifts and labors on an ultimately trivial human enterprise.
    -- George Steiner

  4. #4
    Join Date
    Sep 2002
    Posts
    3
    I'm pretty sure the problem lies in trying to use a CString inside of a struct in the first place. I fooled around with this a few weeks back, and C++ just hates the idea of having a class-based member variable inside of a struct. I would recommend trying it with good old char* and see what happens.

    I am by no means a guru, though, perhaps someone else will be able to provide a better answer.

  5. #5
    Join Date
    Dec 2002
    Location
    phoenix, az
    Posts
    23
    Originally posted by Stompbox
    I'm pretty sure the problem lies in trying to use a CString inside of a struct in the first place.
    a struct is a class, with the default access modifier being public. btw, the code works just fine for me.

  6. #6
    Join Date
    Oct 2001
    Location
    Dublin, Eire
    Posts
    880
    I'm sure of one thing, there' no problem using a class in a struct or in another class. I'm using a lot of CString members in either classes or structures and never had a problem.

    If it was a problem doing that, then C++ would not even be close to be an OO language.

    The problem is definitely elsewhere, but we must hear from codebear to have a chance to identify the problem, if it still exist.
    Elrond
    A chess genius is a human being who focuses vast, little-understood mental gifts and labors on an ultimately trivial human enterprise.
    -- George Steiner

  7. #7
    Join Date
    Dec 2002
    Posts
    1
    Thanks for your input!

    Elrond, about the code:
    - the variable was outside of any functions and static in the CPP file, so I believe that makes it private to all funcitions in the CPP.
    - the index array, pos, was not going OOB since it was failing on an index of 0 and the array was hard-coded to size 100.

    I actually got it to work by making the CString member a char *, and then initializing a char[] using the length of the string. But I'm still interested in why this didn't work with the CString implementation.

    Given the code earlier, I know that an array of the struct type is declared - but when would it run the constructors on the struct? Maybe the CString constructor never has the chance to run. If that's the case, then how would you implement something like this?

  8. #8
    Join Date
    Oct 2001
    Location
    Dublin, Eire
    Posts
    880
    An assertion error usually gives you a file name and a line. Have you tried to look at it? If not, give it here so we might try to find out what going on.

    I've tried your code and could find no problem. It executes perfectly without any assertin error.
    Elrond
    A chess genius is a human being who focuses vast, little-understood mental gifts and labors on an ultimately trivial human enterprise.
    -- George Steiner

  9. #9
    Join Date
    Dec 2002
    Posts
    1
    I isolated the code fragment and dumped it into its own project - you're right - it runs without any assertion errors. I now suspect the issue might lie with something else in the codebase / project that I am working on (it's much much larger) and perhaps something subtle that someone forgot to mention to me.

    But for the assertion, it was in AFX.INL on line 122, which is:

    { ASSERT(m_pchData != NULL); return ((CStringData*)m_pchData)-1; }

    Turns out that the m_pchData variable was NULL. I wasn't sure what strategy I should have used to trace this error - how would one go on to debug something like this?

  10. #10
    Join Date
    Oct 2001
    Location
    Dublin, Eire
    Posts
    880
    A first solution is to create a constructor for your structure (as a struct is a class, you can do it as for any other class). Then put a break point into it and check if the constructor is called before your first call to the function someFunction.

    The initialisation at the start of the program can sometimes be in an unexpected order that will give you unexpected results.

    Just imagine that you call this function in the constructor of your application object. This one is a global variable as well and its contructor might be called before your array is constructed.
    Elrond
    A chess genius is a human being who focuses vast, little-understood mental gifts and labors on an ultimately trivial human enterprise.
    -- George Steiner

  11. #11
    Join Date
    Dec 2002
    Posts
    1
    That is a really good point - someFunction is actually being called within a constructor of another object (not the application object per se).

    I made a constructor for the struct and put in a break point - it looks like the array is being initialized (and the constructor is being called) before the function is called. The callstack indicates that WinMainCRTStartup is being run to construct it. Perhaps by supplying my own constructor, I have already solved the problem.

    But taking into account what was said earlier, I think it's probably a good idea to get into the practice of initializing some of these other objects before the constructor runs (e.g. for my future code). I've seen syntax like this before:

    myClass::myClass ( )
    : anotherClass (some_arg),
    yetAnotherClass (some_arg)
    {
    ...
    anotherClass->setSomething ( some_arg);
    ...
    }

    I believe that anotherClass and yetAnotherClass will be constructed in that order before the myClass constructor runs. I'm not sure what this was called ....shadow something?

    Is this an appropriate practice?

  12. #12
    Join Date
    Oct 2001
    Location
    Dublin, Eire
    Posts
    880
    I don't know the name, but if you can have the arguments for the constructors of the members while the constructor of your class is called, then it is better to initialise your members there:
    Code:
    CMyClass::CMyClass(int i, CAnotherClass ac) :
      m_i(i), m_ac(ac), m_yac(defaultValue)
    {
      // But sometines you need to check the parameters 
      // to assign the initial value of a member
      if( i = 0 )
        m_bMember = false;
      else
        m_bMember = true;
    }
    Elrond
    A chess genius is a human being who focuses vast, little-understood mental gifts and labors on an ultimately trivial human enterprise.
    -- George Steiner

  13. #13
    Join Date
    Dec 2002
    Posts
    1

    Thumbs up

    I think I will do that from now on.

    Thanks for all your help Elrond!

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