Strange Behaviour

closed account (zb0S216C)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main()
{
    Container::IBStackLinkedList<int> TList(3u);

    std::cout << TList.Capacity() << " "; // Capacity() #1

    try
    {
        Container::IBStackLinkedList<int> NList(TList.Capacity()); // Capacity() #2
    }

    catch(Container::IBFastException &E)
    {
        std::cout << E.Size; // Prints a very large number.
    }
}

TList's constructor internally allocates 3 nodes. I then print the capacity of TList (Capacity() returns the amount of nodes allocated internally) which is the expected result of 3. This is where the behaviour becomes strange: NList attempts to internally allocate the same amount of nodes as TList. Now, you'd think 3 nodes would've been allocated - you'd be wrong. In actual fact, over 200,000 nodes were allocated; this caused new to fail.

Nothing happened between the two Capacity() calls. So how did the result become so large? Note that IBFastException::Size simply contains the amount of nodes that was requested.

Ideas?

Wazzak
I know nothing about those classes, but... What's the code for Container::IBStackLinkedList::Capacity and Container::IBStackLinkedList::IBStackLinkedList 's Parameter Type?
I hope it is a unsigned int, i see a 3u there.
closed account (zb0S216C)
Here are the definitions of the said functions:

IBStackLinkedList::Capacity():

1
2
3
4
5
template <typename Type>
inline Base::IBUSignedInt const &IBStackLinkedList<Type>::Capacity() const
{
    return((!this->Root__) ? 0U : ((this->Tail__ - this->Root__) + 1));
}

This function simply obtains the distance between Root__ and Tail__, and then adds 1 to it. The 1 gives the capacity, not the index.

Constructor:

1
2
3
4
5
6
7
template <typename Type>
IBStackLinkedList<Type>::IBStackLinkedList(Base::IBUSignedInt const &ReserveSize)
    : Root__(Base::IB_NULL), Tail__(Base::IB_NULL), Next__(Base::IB_NULL)
{
    // Allocate the specified amount of nodes.
    this->Allocate(ReserveSize);
}

IBStackLinkedList::Allocate() simply reserves space for a specified number of nodes.

Wazzak
You are leaving out too much information.
Go to the constructor and check the parameter received.

¿Are you trying to make a deque? ¿or an index list?
Try for a moment to set Root__ and Tail__ to signed, or simply have a "Difference" Function like this:
1
2
3
4
template <typename T> T Difference(const T& First, const T& Second)
{
    return (First > Second) ? (First - Second) : (Second - First);
}

and use it in place of the Tail__ - Root__

(Quite strange it only happens once anyways, gotta try giving more options to try, as I'm almost sure above thing will do nothing)
Constructor:
1
2
3
4
5
6
7
template <typename Type>
IBStackLinkedList<Type>::IBStackLinkedList(Base::IBUSignedInt const &ReserveSize)
    : Root__(Base::IB_NULL), Tail__(Base::IB_NULL), Next__(Base::IB_NULL)
{
    // Allocate the specified amount of nodes.
    this->Allocate(ReserveSize);
}
Base::IBUSignedInt

Signed Int? Or it was a typo to Unsigned Int? Maybe you should change it to unsigned, may it be that that gives troubles? It looks like a signed-unsigned trouble, maybe you should change your warning level and check signed/unsigned implicit conversion.
Also check if Allocate sets Root__ and Tail__ to the right values.

Anyways @ne555 this looks like a IBStackLinkedList, notice: LinkedList.
Last edited on
closed account (zb0S216C)
@ne555: Did you read my first post? The exception thrown (IBFastException) contains the size given to IBStackLinkedList::Allocate() if the call fails. IBStackLinkedList::Allocate() calls new and sets the internal pointers to their respective positions. That's it.

Also, no, I'm not making either (note the "Stack" in the name).

@EssGeEich: I cannot set neither Root__ nor Tail__ to signed because they are pointers. Also, Base::IBUSignedInt isn't a typo; it's a type-definition of unsigned int.

Here's the IBStackLinkedList::Allocate() function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template <typename Type>
Base::IBBool const IBStackLinkedList<Type>::Allocate(Base::IBUSignedInt const &Size)
{
    // Do not allocate a new block if there's one already.
    if(this->Root__) return(false);

    Container::IBLinkedListNode<Type> *New(static_cast<Container::IBLinkedListNode<Type> *>(
        operator new [] ((((Size > 0) ? Size : IBStackLinkedList<Type>::DEF_SIZE) * sizeof(Container::IBLinkedListNode<Type>)),
        std::nothrow)));

    if(!New) throw(IBFastException(Size));

    this->Root__ = New;
    this->Tail__ = (this->Root__ + (Size - 1));
    this->Next__ = this->Root__;
    return(true);
}

Edit: DEF_SIZE is a constant unsigned int with a value of 1024.
Wazzak
Last edited on
closed account (zb0S216C)
Solved!

It turns out I made a small error in the definition: I returned a reference to an implicitly created temporary object. The resulting value of IBStackLinkedList::Capacity() was a temporary Base::IBUSignedInt object who's lifetime ended as soon as the call had finished. I removed the ampersand and now it functions correctly.

Thanks for your help, EssGeEich :) I appreciate it.

Wazzak
Well, my help didn't really change much, lol.
Topic archived. No new replies allowed.