Accessing to second level object through pointers after OnClicked call causing CRASH

Hello,

I’m just moving my stuff from Unity to Unreal (5.1) and just observed something strange for me (maybe because of moving from c# to c++ and lack of knowledge).

I’ve created new plugin/module with window and created and put new widgets inside. I was trying to change relation structure between widgets but always get the same result which I attached below.

Final structure of module is like:

  • MainWindowModule
  • MainWidget (with some navigation buttons) [inside MainWindowModule]
    • ChildWidget (with some text editors , lists, etc) [inside MainWidget]

In MainWidget I keep pointer to the MainWindowModule

class SLATEQUICKSTARTWINDOW_API SQuickStartWindowMenu : public SCompoundWidget
{
private:
	FSlateQuickstartWindowModule* MainWindowModule;

public:
	SLATE_BEGIN_ARGS(SQuickStartWindowMenu)		
		{
		}
		SLATE_ARGUMENT(FSlateQuickstartWindowModule*, MainWindowModule)
	SLATE_END_ARGS()

	TSharedPtr<SAGFScenesManager> ScenesManagerWidget;

	/** Constructs this widget with InArgs */
	void Construct(const FArguments& InArgs);

	FReply OnFirstButtonClicked();
	FReply OnSecondButtonClicked();
	void LOGSOMETHING(); 
	FSlateQuickstartWindowModule* GetWindowModule();
}

and filling it with (in OnSpawnPluginTab method of FSlateQuickstartWindowModule)

SAssignNew(MainMenuWidget, SQuickStartWindowMenu).MainWindowModule(this)

In ChildWidget the code looks similar

class SLATEQUICKSTARTWINDOW_API SAGFScenesManager : public SCompoundWidget
{

private:
	SQuickStartWindowMenu* MainWindowMenuWidget;

public:
	SLATE_BEGIN_ARGS(SAGFScenesManager)
		{
		}
		SLATE_ARGUMENT(SQuickStartWindowMenu*, MainWindowMenuWidget)
	SLATE_END_ARGS()

	/** Constructs this widget with InArgs */
	void Construct(const FArguments& InArgs);

	FReply OnAddSceneButtonClicked();
	void LOGSOMETHING();
	SQuickStartWindowMenu* GetMenuWidget();
};

and filling it with (in Construct method of SQuickStartWindowMenu)

SAssignNew(ScenesManagerWidget, SAGFScenesManager).MainWindowMenuWidget(this)

As you can see each widget has it own LOGSOMETHING method (just sending something to log using UE_LOG). MainWindowModule also has it.

MainWidget and ChildWidget have their own buttons, and here is something which I don’t understand, I can just call only methods from used button widget and methods from the higher level widget.

when calling this on the lowest level in ChildWidget everything is OK

LOGSOMETHING();
MainWindowMenuWidget->LOGSOMETHING();

but calling this on the lowest level

MainWindowMenuWidget->GetWindowModule()->LOGSOMETHING();

crashing editor and throwing this:

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x0000000000000338

UnrealEditor_SlateQuickstartWindow_patch_0!SQuickStartWindowMenu::LOGSOMETHING() [D:\UnrealProjects\UnrealEdExtTest01\Plugins\SlateQuickstartWindow\Source\SlateQuickstartWindow\Private\AGFWidgets\SQuickStartWindowMenu.cpp:118]
UnrealEditor_SlateQuickstartWindow_patch_0!SAGFScenesManager::LOGSOMETHING() [D:\UnrealProjects\UnrealEdExtTest01\Plugins\SlateQuickstartWindow\Source\SlateQuickstartWindow\Private\AGFWidgets\Managers\SAGFScenesManager.cpp:102]
UnrealEditor_SlateQuickstartWindow_patch_0!SAGFScenesManager::OnAddSceneButtonClicked() [D:\UnrealProjects\UnrealEdExtTest01\Plugins\SlateQuickstartWindow\Source\SlateQuickstartWindow\Private\AGFWidgets\Managers\SAGFScenesManager.cpp:93]
UnrealEditor_SlateQuickstartWindow_patch_0!TBaseSPMethodDelegateInstance<0,SAGFScenesManager,1,FReply __cdecl(void),FDefaultDelegateUserPolicy>::Execute() [D:\Epic Games\UE_5.1\Engine\Source\Runtime\Core\Public\Delegates\DelegateInstancesImpl.h:295]

UnrealEditor_Slate ...

of course calling

MainWindowModule->LOGSOMETHING();

in the MainWidget works fine.

I’t looks like I cant get access to the second level pointer.

Any ideas? Thanks for any help with this!

Ok guys, I’ve found a solution.

Because of unknown to me reasons setting MainWindowModule and MainWindowMenuWidget pointers doesn’t work through Slate Arguments, I had to changed code from this

class SLATEQUICKSTARTWINDOW_API SQuickStartWindowMenu : public SCompoundWidget
{
private:
	FSlateQuickstartWindowModule* MainWindowModule;

public:
	SLATE_BEGIN_ARGS(SQuickStartWindowMenu)		
		{
		}
		SLATE_ARGUMENT(FSlateQuickstartWindowModule*, MainWindowModule)
	SLATE_END_ARGS()

	TSharedPtr<SAGFScenesManager> ScenesManagerWidget;

	/** Constructs this widget with InArgs */
	void Construct(const FArguments& InArgs);

	FReply OnFirstButtonClicked();
	FReply OnSecondButtonClicked();
	void LOGSOMETHING(); 
	FSlateQuickstartWindowModule* GetWindowModule();
}

to this

class SLATEQUICKSTARTWINDOW_API SQuickStartWindowMenu : public SCompoundWidget
{

private:
	FSlateQuickstartWindowModule* MainWindowModule = nullptr;

public:
	SLATE_BEGIN_ARGS(SQuickStartWindowMenu)		
		{
		}		
	SLATE_END_ARGS()

	TSharedPtr<SAGFScenesManager> ScenesManagerWidget;

	/** Constructs this widget with InArgs */
	void Construct(const FArguments& InArgs, FSlateQuickstartWindowModule* mainWindowModule);

	FReply OnScenesButtonClicked();
	FReply OnObjectsButtonClicked();
	void LOGSOMETHING(); 
	FSlateQuickstartWindowModule* GetWindowModule();
};

and changed filling pointer from

SAssignNew(MainMenuWidget, SQuickStartWindowMenu).MainWindowModule(this)

to

SAssignNew(MainMenuWidget, SQuickStartWindowMenu, this)

and after changing Construct method I added new line

void SQuickStartWindowMenu::Construct(const FArguments& InArgs, FSlateQuickstartWindowModule* mainWindowModule)
{   
    MainWindowModule = mainWindowModule;
    ...
}

I did the same things to the second widget and now all pointers are set properly in all widgets, and the crush effect disappeared