Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

30
Rolando V. Raqueño Monday, June 27, 202 2 Modal Widgets, Pointers, and Memory Leaks

Transcript of Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Page 1: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

Modal Widgets, Pointers, and Memory Leaks

Page 2: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

Modal Widgets

• Modal Widgets also known as pop-up widgets are a means to simplify a GUI interface by allowing an input window to be presented to the user at an appropriate time

• Because a new window is created and destroyed, there needs to be a mechanism to pass the values specified to the used back to the calling widget.

Page 3: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

Variables inside a Widget

• Remember that variables defined in a widget only exist as long as that widget exists

• We have to somehow pass out any values defined to a calling function

Page 4: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

pop_fslider Case Study

• Problem: We want to create a simple slider that a user can call from the IDL prompt and return to the calling routine a floating point value reflecting the position of the floating point slider (CW_FSLIDER)

IDL> a = pop_fslider()

Page 5: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

pop_fslider.pro (initial version - Widget Definition)

function pop_fslider

base = Widget_Base( /column )

fslider = CW_Fslider( base, /edit )

quit_button = Widget_Button( base, value="Quit", event_pro='quit_event' )

Widget_Control, base, /realize

global_data={ fslider_id: fslider, fslider_value: 0.0 }

Widget_Control, base, set_uvalue=global_data

Xmanager, 'pop_fslider', base, event_handler='pop_fslider_event'

Widget_Control, base, get_uvalue=global_data

print,’In Widget Definition=‘, global_data.fslider_value

return, global_data.fslider_value

end

Page 6: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

pop_fslider.pro (initial version -

Event Handler Definition)pro pop_fslider_event, event Widget_Control, event.top, get_uvalue=global_data Widget_Control, global_data.fslider_id,

get_value=fslider_value global_data.fslider_value=fslider_value print,’In Event Handler =‘, global_data.fslider_value Widget_Control, event.top, set_uvalue=global_dataend

pro quit_event, event Widget_Control, event.top, /destroyend

Page 7: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

pop_fslider.pro (initial version output)

IDL> a=pop_fslider()In Event Handler = 44.0000In Event Handler = 39.0000In Event Handler = 39.0000In Event Handler = 42.0000% WIDGET_CONTROL: Invalid widget identifier: 1.% Execution halted at: POP_FSLIDER 28 pop_fslider.pro

% $MAIN$

Page 8: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

pop_fslider.pro (initial version - Widget Definition)

function pop_fslider base = Widget_Base( /column ) fslider = CW_Fslider( base, /edit ) quit_button = Widget_Button( base, value="Quit",

event_pro='quit_event' ) Widget_Control, base, /realize global_data={ fslider_id: fslider, fslider_value: 0.0 } Widget_Control, base, set_uvalue=global_data Xmanager, 'pop_fslider', base,

event_handler='pop_fslider_event' Widget_Control, base, get_uvalue=global_data print,’In Widget Definition=‘, global_data.fslider_value return, global_data.fslider_valueend

Page 9: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

pop_fslider.pro (initial version - Event Definition)

• This does not work because the widget has already been destroyed and along with it the uvalue that was being stored

• To make this work, we need to use what IDL calls handles (or in C/C++ the concept of pointers)

Page 10: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

IDL Pointers

Page 11: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

What are Pointers?• Pointers are special variables that point to

memory locations that are explicitly allocated by the user.

• It is different from other variables in that the memory location pointed to by a handle are persistent (i.e., they exist from one routine to another)

• It is also the user’s responsibility to destroy the allocated memory

Page 12: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

Uses of Handles

• Management of persistent data

• Minimizes passing around large data structures

• Linked lists data structures

• Tree data structures

Page 13: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

Syntax for managing Pointers

• Ptr_new (Create a NULL pointer)IDL> image_pointer = ptr_new()

• Ptr_new (Pointer to existing data)IDL> image = bindgen(5,5)IDL> image_pointer = ptr_new(image)

• To access values referenced by pointerIDL> print, (*image_pointer)[0,0]

Page 14: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

Sample use of Handle RoutinesIDL> image=bindgen(5,5)IDL> image_pointer = ptr_new(image)IDL> help,imageIMAGE BYTE = Array[5, 5]IDL> help, image_pointerIMAGE_POINTER POINTER = <PtrHeapVar5>

IDL> print, (*image_pointer)[0,0]

Page 15: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

pop_fslider.pro (new version - Widget Definition)

function pop_fslider ... Widget_Control, base, /realize pointer = ptr_new(0.0) global_data={ fslider_id: fslider, ptr: pointer } Widget_Control, base, set_uvalue=global_data Xmanager, 'pop_fslider', base,

event_handler='pop_fslider_event' fslider_value = *pointer return, fslider_valueend

Page 16: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

pop_fslider.pro (new version -

Event Handler Definition)pro pop_fslider_event, event Widget_Control, event.top, get_uvalue=global_data Widget_Control, global_data.fslider_id,

get_value=fslider_value pointer = global_data.ptr *pointer = fslider_value print,’In Event Handler =‘, fslider_valueend

pro quit_event, event Widget_Control, event.top, /destroyend

Page 17: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

Result of pop_fslider.pro

IDL> a=pop_fslider()In Event Handler = 40.0000In Event Handler = 43.0000In Event Handler = 42.0000IDL> print,a 42.0000

Page 18: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

Get_preview_image EXAMPLE

A more convoluted example of pointers to a structure containing

pointers.

Page 19: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

Get_preview_image.pro

• Allows you to make the following call at the IDL command line

IDL> a=get_preview_image()

• A widget pops up that allows you to select and preview the image

• When done, variable ‘a’ contains the image

Page 20: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

Screenshot of get_preview_image

Page 21: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

Widget Definition of get_preview_image.pro

function get_preview_image base = Widget_Base( Title='Enter Value', /column ) window_id = Widget_Draw(base, xsize=256, ysize=256) file_button_id=Widget_Button(base,value="File",event_pro='file_event') quit_button_id=Widget_Button(base,value="Quit",event_pro='quit_event') Widget_Control, base, /realize Widget_Control, window_id, get_value=display_id image_ptr = ptr_new() global_data = { window: window_id, display: display_id, $ file_button: file_button_id, $ quit_button: quit_button_id,image: image_ptr } global_ptr = ptr_new( global_data ) Widget_Control, base, set_uvalue=global_ptr Xmanager,'get_preview_image',base image = *((*global_ptr).image) return, imageend

Page 22: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

Event Handler of get_preview_image.pro

pro file_event, event file_name = pickfile() print,"Reading in image ...“ & s = systime(/seconds) read_ppm, file_name, image e = systime(/seconds) & print,"Done", e-s,"Seconds“ & print,"" Widget_Control, event.top, get_uvalue=global_data display_id = (*global_data).display wset, display_id tvscl, congrid(image, 256, 256) image_ptr = (*global_data).image image_ptr = ptr_new( image ) (*global_data).image=image_ptrend

pro quit_event, event Widget_Control, event.top, /destroyend

Page 23: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

Program seems to run fine

• Test with your favorite image file

• Next,– Create a 10,000 x 10,000 pgm test image

Page 24: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

To create a LARGE test image

% pgmramp –ellipse 10000 10000 > pgmramp.pgm

Page 25: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

Try to run the program 10 times

IDL> a=get_preview_image()

IDL> a=get_preview_image()

IDL> a=get_preview_image()

IDL> a=get_preview_image()

IDL> a=get_preview_image()

Page 26: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

Program Bombs after several tries

Reading in image ...% Compiled module: READ_PPM.Done 10.323603Seconds

% Compiled module: CONGRID.Reading in image ...Done 10.746588Seconds

Reading in image ...Done 11.441382Seconds

Reading in image ...Done 22.284706Seconds

% XMANAGER: Caught unexpected error from client application. Message follows...

% Unable to allocate memory: to make array.

Page 27: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

It Dies because…

• There is a memory leak

• This occurs when the program does not free up memory allocated when using pointers

• Repeated runs in the event handler causes memory to be eaten up until there is very little left

Page 28: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

FIX to Event Handler of get_preview_image.pro

pro file_event, event file_name = pickfile() print,"Reading in image ...“ & s = systime(/seconds) read_ppm, file_name, image e = systime(/seconds) & print,"Done", e-s,"Seconds“ & print,"" Widget_Control, event.top, get_uvalue=global_data display_id = (*global_data).display wset, display_id tvscl, congrid(image, 256, 256) image_ptr = (*global_data).image ptr_free, image_ptr image_ptr = ptr_new( image ) (*global_data).image=image_ptrend

pro quit_event, event Widget_Control, event.top, /destroyend

Page 29: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

Program should now work

• Ptr_free will make sure that the previous pointer reference will be deallocated

Page 30: Rolando V. RaqueñoSunday, October 18, 2015 Modal Widgets, Pointers, and Memory Leaks.

Rolando V. Raqueño Thursday, April 20, 2023

Moral

• Pointers can save memory and burden of passing around large structure

• Difficult to interpret dereferencing of pointers

• Memory Leaks are prevalent requiring repeated tests with memory intensive data sets