[C++] Adding widget to viewport causes crash

I suspect that your UI Objects (vLayout, test etc) are Garbage collected…

You are creating new objects but you are storing the references about them on the stack. In doing so, at the end of your BeginPlay method, these newly created objects are not referenced by anyone anymore. Therefore, they are garbage collected and the ViewPort reference something which is not in memory anymore, leading to a crash.

Try creating class variables with UPROPERTY() referencing them and see if it solves the problem.
Something like that (in your header):

class MYPROJECT_API AMHUD : public AHUD
{
   GENERATED_BODY()

private:
   UPROPERTY()
   UVerticalBox* vLayout;
     
   UPROPERTY()
   UButton* test;
    
    UPROPERTY() 
    UVerticalBoxSlot* buttonSlot;

// Rest of the code
};

Also, attaching the debugger to your game could help track down the issue, thanks to the call stack leading to the crash.

Reading this doc:
https://docs.unrealengine.com/en-US/Programming/UnrealArchitecture/Objects/Optimizations (the section “Garbage Collection”)

And this doc: https://docs.unrealengine.com/en-US/Programming/UnrealArchitecture/Objects/Optimizations

should help you understand this process. :slight_smile:

Edit: the thing making me not sure about that is the use of the “UWidget::TakeWidget()” method. Don’t know what it does about ownership…

Am I doing something wrong in creating these widgets like this, because if I remove this code my game will run just fine.

Also the game will run for about 1 minute before crashing.

void AMHUD::BeginPlay()
    {
    	Super::BeginPlay();
    
    	UVerticalBox* vLayout = NewObject<UVerticalBox>(this, UVerticalBox::StaticClass());
    
    	UButton* test = NewObject<UButton>(vLayout, UButton::StaticClass());
    
    	UVerticalBoxSlot* buttonSlot = vLayout->AddChildToVerticalBox(test);
    
    	buttonSlot->SetHorizontalAlignment(EHorizontalAlignment::HAlign_Center);
    	buttonSlot->SetVerticalAlignment(EVerticalAlignment::VAlign_Center);
    
    	GEngine->GameViewport->AddViewportWidgetContent(vLayout->TakeWidget());
    	
    }

Thank you! This actually solved it. And I only need to keep a refrence to my parent widget because it itself will hold refrences to it’s children.

Awesome, glad I could help!

Thank you!