Thread: Enum as array

  1. #16
    Registered User
    Join Date
    Mar 2009
    Posts
    102
    OK, now am confused. I have a hashtable class, this class contains a dynamic array that contains objects. Now, I want to have a way of knowing which index is occupied, deleted, or unoccupied. Before, I was using another dynamic boolean array that told me which index is un(occupied). It worked well till I realised that I needed a third state. The problem now is that it doesn't look like enum will act as a replacement. For a start, I can't declare it dynamically and I need this because the table will be resized. For the boolean, it was easy:

    Code:
    bool * states;
    
    states = new bool [initialTableSize];
    then with a loop, filled each index with the default unoccupied. Later on, then as I filled each position, change status accordingly. When rehashing (resizing table), I declared another local dynamic array, copied the values, and rehashed values. Everything worked well. But wit enum, I am confused.

    I can't declare it as a pointer, can't say States * states; can't resize it with table. So, is there a way, analogous to the boolean array but with 3 states, this can be done?

    Something like;

    Code:
    States * states;
    
    states = new States[100]//declared 100 states
    
    //fill each index with default unoccupied states
    for(int i = 0; i < 100; ++)
    states[i] = unoccupied;
    Then later just use it, changing the value of each states to one of the three predefined states. And be able to increase the size of the states array. Or am I overcomplicating things?

  2. #17
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Dontgiveup
    I can't declare it as a pointer, can't say States * states
    Eh, but you can. Perhaps you should post the smallest and simplest program that you expect should compile but which demonstrates this problem.

    Quote Originally Posted by Dontgiveup
    Then later just use it, changing the value of each states to one of the three predefined states. And be able to increase the size of the states array. Or am I overcomplicating things?
    Yes. It would be simpler to use a std::vector<State>.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #18
    Registered User antred's Avatar
    Join Date
    Apr 2012
    Location
    Germany
    Posts
    257
    This is not really on topic, but why do people keep doing this:

    Quote Originally Posted by Dontgiveup View Post
    Code:
    States * states;
    
    states = new States[100]//declared 100 states
    ??

    Why not just do

    Code:
    States* states = new States[100];
    and be done with it?
    You gain absolutely nothing from using two lines for something so trivial. In fact you incur the risk of uninitialized pointers if you add more coder later between the declaration of the pointer and its initialization.
    Also, by condensing this into one statement, you can even make the pointer const (provided that you don't need to modify it later).

    Code:
    States* const states = new States[100];

  4. #19
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Well I don't think it applies to new as much because new throws an exception much of the time when it fails, but I've combined the statement which assigns new memory to a pointer with the if condition that checks it for validity, on more than one occasion. It's only an idiosyncrasy, and it can work safely in a larger program if you care enough to initialize your pointers to NULL.

  5. #20
    Registered User antred's Avatar
    Join Date
    Apr 2012
    Location
    Germany
    Posts
    257
    Quote Originally Posted by whiteflags View Post
    Well I don't think it applies to new as much because new throws an exception much of the time when it fails
    That's not my point. Let me show you what I was getting at.

    Code:
    States* states;
     
    states = new States[100];
    
    for ( std::size_t i = 0; i < 100; ++i )
    {
        ...
    }
    Months later, the program is extended by additional functionality. The developer inserts a few lines of code between the declaration of the pointer and it's initialization.

    Code:
    States* states;
    
    if ( someFlag )
    {
        someFunc();
    }
     
    states = new States[100];
    
    for ( std::size_t i = 0; i < 100; ++i )
    {
        ...
    }
    Add another few months and the developer decides to remove to the recently added stuff (for whatever reason). Unfortunately he ends up removing a little too much.

    Code:
    States* states;
    
    for ( std::size_t i = 0; i < 100; ++i )
    {
        ...
    }
    Now mistakes like that happen, but by spreading out declaration and initialization over 2 statements, you're making yourself a lot more vulnerable to such bugs. I've found a whole ton of bugs similar to this in a number of projects I've inherited. We use a dynamic coder checker (IBM Rational Purify), and in fact the most frequent error it finds are UMRs (Uninitialized Memory Read), most of which are a direct result of developers insisting on deferring initialization of local variables until later, when in most cases it could easily be done right then and there. This style of coding is particularly annoying when it is combined with the old C habit of declaring all local variables at the top of the function.

  6. #21
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by antred
    That's not my point. Let me show you what I was getting at.
    I think you misread whiteflags' statement: the "it" refers to "I've combined the statement which assigns new memory to a pointer with the if condition that checks it for validity", not your statement. This is mitigated by having the check for validity performed immediately after the initialisation.

    Basically, you are recommending that variables be declared near first use such that they are given an appropriate initial value where feasible. Avoiding the use of variables that do not have a desired initial value is one reason; another reason would be that for objects of some class types, creating an object only to overwrite it later is being unnecessarily inefficient.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #22
    Registered User
    Join Date
    Mar 2009
    Posts
    102
    Quote Originally Posted by laserlight View Post
    Eh, but you can. Perhaps you should post the smallest and simplest program that you expect should compile but which demonstrates this problem.
    Yeah thanks, you are right. It was my mistake but I managed to sort it out and all is well. Also, can't use vectors because we are not allowed to use that as we have to design our own data structure and not use predefined data structures in STL. But it is fine and all is well. But I have come across something that I would like if someone could elaborate on its cause.

    Normally, if I have a pointer as a member variable, I can initialise it in an initialisation list thus:

    Code:
    class Test {
    
    bool * test;
    
    Test (): test(false);
    
    }
    and then later allocate dynamic memory for 100 like this:

    Code:
    test = new bool[100];
    my question is, when I am initialising test with false in the initialisation field, what is set to false? Will all the 100 elements I have allocated memory have false or, because this happens later, false here is meaningless as it only sets false to a pointer (akin to initialising pointer to 0)?

    Finally, why would this not work with enum?

    Code:
    enum Example{
    
    state1,
    state2,
    state3
    };
    
    class Test {
    
    State * test;
    
    Test (): test(state1);
    
    }
    compiler gives error: cannot convert Example to Example* in initialization

  8. #23
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Dontgiveup
    when I am initialising test with false in the initialisation field, what is set to false?
    You are initialising a member that is a pointer, therefore, the member pointer is set to false. However, since false is not actually an address, what probably happened is that you initialised the pointer to be a null pointer. It would have been simpler to do so directly instead of writing false. This also explains your second question.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #24
    Registered User R41D3N's Avatar
    Join Date
    Mar 2012
    Location
    ...Beyond Infinity, Behind a KeyBoard...
    Posts
    29
    Quote Originally Posted by laserlight View Post
    You are initialising a member that is a pointer, therefore, the member pointer is set to false. However, since false is not actually an address, what probably happened is that you initialised the pointer to be a null pointer. It would have been simpler to do so directly instead of writing false. This also explains your second question.
    yup it gets set to null, a simple change from false to true shows the problem

    Quote Originally Posted by Dontgiveup View Post
    Yeah thanks, you are right. It was my mistake but I managed to sort it out and all is well. Also, can't use vectors because we are not allowed to use that as we have to design our own data structure and not use predefined data structures in STL.
    why not just create your own list then, would be so much easier than the size constraint in case of arrays ...
    Last edited by R41D3N; 06-16-2012 at 12:26 PM. Reason: Multipost

  10. #25
    Registered User
    Join Date
    Mar 2009
    Posts
    102
    Quote Originally Posted by laserlight View Post
    You are initialising a member that is a pointer, therefore, the member pointer is set to false. However, since false is not actually an address, what probably happened is that you initialised the pointer to be a null pointer. It would have been simpler to do so directly instead of writing false. This also explains your second question.
    Thanks. I think that is clear. So basically, if you want to initialise a pointer, just initialise it as null and don't initialise it with some other funny stuff.

    Is there any way that one can for example initialise a dynamic array with initial default values in the initialisation list. Something like:

    Code:
    Test () : test(new bool[100]); //this works but test has undefined values
    so is there anyway I can say in the initialisation list: "Fill test with 100 false default values"?

  11. #26
    Registered User R41D3N's Avatar
    Join Date
    Mar 2012
    Location
    ...Beyond Infinity, Behind a KeyBoard...
    Posts
    29
    Quote Originally Posted by Dontgiveup View Post
    Code:
    Test () : test(new bool[100]); //this works but test has undefined values
    so is there anyway I can say in the initialisation list: "Fill test with 100 false default values"?
    Cant you just use:

    Code:
    fill(test, test+100, false);

  12. #27
    Registered User
    Join Date
    Mar 2009
    Posts
    102
    Quote Originally Posted by R41D3N View Post
    Cant you just use:

    Code:
    fill(test, test+100, false);
    or

    Code:
    bool* t; t = new bool [100] {false};
    I know of course that I can use another method. I am already using an init method in the constructor body to fill in. But I was thinking of whether it is possible with the constructor (initialisation fields).

  13. #28
    Registered User R41D3N's Avatar
    Join Date
    Mar 2012
    Location
    ...Beyond Infinity, Behind a KeyBoard...
    Posts
    29
    Quote Originally Posted by Dontgiveup View Post
    Code:
    Test () : test(new bool[100]); //this works but test has undefined values
    Just compiled it, its not undefined. All elements are initialized to false by default.

    Code
    Last edited by R41D3N; 06-16-2012 at 12:46 PM.

  14. #29
    Registered User
    Join Date
    Mar 2009
    Posts
    102
    Quote Originally Posted by R41D3N View Post
    Just compiled it, its not undefined. All elements are initialized to false by default.
    Not sure that is a good idea. I think, and someone correct me if I am wrong, in C++, unless you assign values, everything remains undefined.

  15. #30
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by Dontgiveup View Post
    Not sure that is a good idea. I think, and someone correct me if I am wrong, in C++, unless you assign values, everything remains undefined.
    I think bool's default constructor gets called and it produces false.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Assigning enum types to enum types?
    By see the big C in forum C Programming
    Replies: 10
    Last Post: 12-21-2010, 02:32 AM
  2. enum and 2D array declaration
    By bigbig in forum C Programming
    Replies: 2
    Last Post: 03-30-2010, 11:59 AM
  3. enum constants as array indices
    By hzmonte in forum C Programming
    Replies: 2
    Last Post: 01-23-2006, 08:23 PM
  4. enum Help
    By Bitphire in forum C++ Programming
    Replies: 1
    Last Post: 11-04-2004, 11:03 AM
  5. What enum got to do with it?
    By correlcj in forum C Programming
    Replies: 4
    Last Post: 07-18-2002, 08:12 PM