Not all functions are compiling UE4 C++

I wrote my own template-based TStack class. It’s here:

#pragma once

namespace TStack {
	template<typename T>
	class TStack {
	public:
	void initSize(int size)
	{
		stack = new T[size];
		stackSize = size;
	}

	T pop()
	{
		return stack[--currPoint];
	}
	bool push(T elem)
	{
		if (isFull())
			return false;
		else
			return true;
		currPoint++;
		stack[currPoint] = elem;
	}
	bool isEmpty()
	{
		return (countElems == 0);
	}
	bool isFull()
	{
		return (countElems == stackSize);
	}
	T* stack;
	int currPoint = -1, countElems = 0, stackSize;
	};
}

It compikes OK, without any linker errors. Then I created UFUNCTION testStack() to test this stack:

#pragma optimize("", off)
void UMazeLib::testStack() {
	TStack::TStack<class FString>* stack;
	stack = new TStack::TStack<class FString>;
	stack->initSize(3);
	stack->push(FString(TEXT("1")));

	FString debugStr = FString(TEXT("currPoint = ")) + FString::FromInt(stack->currPoint) + FString(TEXT("; countElems = ")) + FString::FromInt(stack->countElems) + FString(TEXT("; stackSize = ")) + FString::FromInt(stack->stackSize);

	GEngine->AddOnScreenDebugMessage(1, 5.f, FColor::Black, debugStr);

	stack->push(FString(TEXT("2")));

	debugStr = FString(TEXT("currPoint = ")) + FString::FromInt(stack->currPoint) + FString(TEXT("; countElems = ")) + FString::FromInt(stack->countElems) + FString(TEXT("; stackSize = ")) + FString::FromInt(stack->stackSize);

	GEngine->AddOnScreenDebugMessage(1, 5.f, FColor::Black, debugStr);

	stack->push(FString(TEXT("3")));

	debugStr = FString(TEXT("currPoint = ")) + FString::FromInt(stack->currPoint) + FString(TEXT("; countElems = ")) + FString::FromInt(stack->countElems) + FString(TEXT("; stackSize = ")) + FString::FromInt(stack->stackSize);

	GEngine->AddOnScreenDebugMessage(1, 5.f, FColor::Black, debugStr);
}
#pragma optimize("", on)

But it gives me only “currPoint = -1; countElems = 0; stackSize = 3;”, and when I use pop(), UE4 crashes. So please help me.

Hello!

look at TStack::pop()

 return stack[currPoint--]; // if prefix --currPoint it will crash!

When you have only one element,currPoint==0, pop() will return stack[-1]

I changed it to return stack[currPoint–], but it crashes again(compiles OK). And it post me debugStr only 1 time, where currPoint is -1.

As I see it (without having debugged the code myself) is that you are incrementing the index before writing the value to the stack in push() but in isFull() you are testing for index and size for equality. I think this is inconsistent as it will write the last element to memory after the array. Remember for a stack size of 3 you’ll have the indices 0, 1 and 2. So in addition to the fix from azteco you should:

 bool isFull()
 {
     return countElems == stackSize - 1;
 }

If you really need to build your own container classes I would strongly advise to write some unit tests for them also. But better just stick with containers provided by STL (or UE4). Writing such classes in a way that even nearly matches the quality of such long established libraries is a task far from being trivial.

I solved my problem. Mistake was in push() method. As this it was before:

    bool push(T elem)
	{
		if (isFull())
			return false;//return from function
		else 
            return true;//return from function
		currPoint++;//this code will never be runned
		stack[currPoint] = elem;

	}

So now it works. Code is like that:

	bool push(T elem)
	{
		if (isFull())
			return false;
		else {
			currPoint++;
			stack[currPoint] = elem;//now it execute
			return true;
		}
	}

Good to see you solved it!

I was replying this…

Inside push()… After else… Return true;=> must go at the end of the method or the following code will never execute.

Members:
TStack… Better declare it like T* TStack=0;

No need to have currenentpoint plus countelements.
And define currpoint=-1 is bad design, you should leave currpoint and to get use [countelements-1]

so pop()return Tstack[–currelem] will be fine

bool push(T elem)
{
if (isFull())
return false;
// else,leave it
stack[currPoint] = elem;
currPoint++;
return true;
}

I suggest to leave init and define your own constructor…

class TStack {
public:
TStack(int size):stackSize(size),countelements(0)
{
stack = new T[size];//putting in ctpr blocks any re initialize!
}

Ok, I’ll think about this. Thanks all who helped me.