Invalid memory access error

Just starting out? Need help? Post your questions and find answers here.
User avatar
captain_skank
Enthusiast
Enthusiast
Posts: 641
Joined: Fri Oct 06, 2006 3:57 pm
Location: England

Invalid memory access error

Post by captain_skank »

Afternoon all,

Getting a strange error when freeing a gadget and then trying to recreate it.

i have a container gadget that I need to empty, so I first free the gadget using

Code: Select all

If IsGadget(fld_header) :  FreeGadget(fld_header)   : EndIf
then recreate it, but my code is throwing the following error :

Code: Select all

[13:45:31] [ERROR] Invalid memory access. (write error at address 0)
[13:45:46] The Program was killed.
Any idea why this would be happening ?
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: Invalid memory access error

Post by ts-soft »

I think, you are using #PB_Any? and the error comes with recreate it?
Without any code, i can't help.
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
captain_skank
Enthusiast
Enthusiast
Posts: 641
Joined: Fri Oct 06, 2006 3:57 pm
Location: England

Re: Invalid memory access error

Post by captain_skank »

Hi ts_soft.

Yep using #pb_any, didn't think this would be a problem though.

Sorry for not posting code but it's a bit long and very messy :)
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: Invalid memory access error

Post by ts-soft »

With #PB_Any you can't use the same ID for new created Gadgets! You have to use a new #PB_Any ID!
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
captain_skank
Enthusiast
Enthusiast
Posts: 641
Joined: Fri Oct 06, 2006 3:57 pm
Location: England

Re: Invalid memory access error

Post by captain_skank »

Thanks for the reply

I think it's something to do with changing to another window and then changing back.

The folowing code works ok before i change window

Code: Select all

  
;kill the fld_display
  FreeGadget(fld_display)
  
 Global fld_display = ScrollAreaGadget(#PB_Any, 15, 130, 970, 400, 940, 1000, #PB_ScrollArea_BorderLess)
 CloseGadgetList()
but once I open and then close another window and return to the main window it crashes when i try to recreate ( or use ) the fld_display gagdet.
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: Invalid memory access error

Post by ts-soft »

captain_skank wrote:I think it's something to do with changing to another window and then changing back.
It have to do with #PB_Any and ID. An ID, created with #PB_Any is a MemoryPointer, but you can't use a MemoryPointer
to recreate a Gadget (or something else).
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
captain_skank
Enthusiast
Enthusiast
Posts: 641
Joined: Fri Oct 06, 2006 3:57 pm
Location: England

Re: Invalid memory access error

Post by captain_skank »

OK Thanks for that.

I've now tried it with an enumerated constant - still get the same error.

Looks like i'll have to disable stuff and turn it on section by section until i find whats causing it :cry:

It's odd though because freeing the gadget and then regenerating works fine and repeatedly with both #pb_any and an enumerated constant, but once I open and close a sub form it stops working by throwing the memory error.

Anyhoo thanks for the pointers ( no pun intended ) :lol:
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Invalid memory access error

Post by netmaestro »

You're storing the return value of #PB_Any in a variable. Then you talk about opening and closing a sub form and then there's the memory error. Is it possible that you jumped into and/or out of a procedure in the course of doing this and lost your access to the variable because it was no longer within the same scope? You can easily determine if this is the case by finding the line it's dying on, and just before that debug your variable and see if it's zero and then End (so as not to crash on the next line). If it isn't zero, see if it can pass IsGadget(). You'll suss out the problem pretty quickly like this, just keep coming up with ideas and hack away.
BERESHEIT
User avatar
captain_skank
Enthusiast
Enthusiast
Posts: 641
Joined: Fri Oct 06, 2006 3:57 pm
Location: England

Re: Invalid memory access error

Post by captain_skank »

OK, a judicious bit of hacking this morning has led me to what triggers the problem.

Firstly an explanation.

I have my main window which has a scrollareagadget which the user populates on the fly by adding records. when finished they press a button and a second window opens which displays status messages as an email is sent. when finished this returns to the main window which clears the frees the scrollareagadget and we can start again. ( i've simplified this )

No the email status window uses a thread to display the ongoing email status and it's this that seems to cause this invalid memory issue, because if i disable it and close the form manualy the main form doesn't thow the error and works as required.

My problem is, i need the thread otherwise the email status is not updated real time it just waits until the process is complete then updates the status in one hit.

I do use the isgadget function and that proves that gadget still exist's and i've tried using an enumerated gadget and a gadget using #pb_any but get the same error. i've also check to see if the thread is still open with isthread().

It's a real head scratcher and I can't post code as it relies on database access amongst other things.

Gonna have to find a way of displaying status without a thread i guess.
User avatar
TI-994A
Addict
Addict
Posts: 2720
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Invalid memory access error

Post by TI-994A »

captain_skank wrote:...I can't post code as it relies on database access amongst other things.
Still, a glimpse of the code could help find the fault.

Fresh eyes. :wink:
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
captain_skank
Enthusiast
Enthusiast
Posts: 641
Joined: Fri Oct 06, 2006 3:57 pm
Location: England

Re: Invalid memory access error

Post by captain_skank »

Right then - took out the thread and a liberal spinkiling of

Code: Select all

While WindowEvent():Wend
to imitate the thread has fixed the issue.

However i'll post the two offending procedures ( although you won't be able to run them ) but as you say fresh eye :)

Code: Select all

Procedure window_send_email(start_date.i)

  Global window_send_email = OpenWindow(#PB_Any, 164, 63, 330, 230, "Sending request email", #PB_Window_BorderLess|#PB_Window_ScreenCentered)
  
  If window_send_email
    
    StickyWindow(window_send_email, #True)
    DisableWindow(window_main, #True)
    
    update_log_file("Sending request email - opened form ", window_send_email)
    
    width.i = WindowWidth(window_send_email)
    height.i = WindowHeight(window_send_email)
    
    Global GBL_send_email_background = window_background_icon_bar(window_send_email, #WIN_STANDARD, 0, 0, width, height, hex_decode(GBL_colour_scheme), "Sending request email", #yes, #yes, #yes, #no)
    
    Global btn_send_email_min.i = CanvasGadget(#PB_Any, width-50, 0, 20, 20)
      form_control_button(btn_send_email_min, icn_minimise)
      GadgetToolTip(btn_send_email_min, "Minimise")
    
    Global btn_send_email_close.i = CanvasGadget(#PB_Any, width-28, 0, 20, 20)
      form_control_button(btn_send_email_close, icn_close)
      GadgetToolTip(btn_send_email_close, "Close")
      
    gadget_GBL_display_row.i = 35
    
    fld_send_email_status = EditorGadget(#PB_Any , 15, gadget_GBL_display_row, 300, 160, #PB_Editor_WordWrap|#PB_Editor_ReadOnly)
      SetGadgetText(fld_send_email_status, "")
      
    gadget_GBL_display_row + 165
      
    fld_send_email_progress= ProgressBarGadget(#PB_Any , 15, gadget_GBL_display_row, WindowWidth(window_send_email)-30, 20, 0, 100, #PB_ProgressBar_Smooth)
    
    ; repaint the calling window
    RedrawWindow_(WindowID(window_send_email),#NUL,#NUL,#RDW_ALLCHILDREN|#RDW_INVALIDATE)
    
    While WindowEvent():Wend
    
  Else
    update_log_file("engineering_frm_time_manager - window_send_email, UNABLE TO OPEN ", window_main)   
    window_warning("PAPERCLIP Error", "Sorry I was unable to open the engineering_frm_time_manager - window_send_email." + Chr(13) + "It could be locked Or may Not exist", "YES", window_send_email, 200)
    End    
  EndIf
  
  timer = CreateThread(@send_emails(), start_date)
  
  window_send_email_status = 0
  
  Repeat
    Event = WaitWindowEvent()
    Select Event
          
      ; enable dragging of window
      Case #WM_LBUTTONDOWN
        SendMessage_(WindowID(window_send_email), #WM_NCLBUTTONDOWN, #HTCAPTION , #Null)
        
      Case #PB_Event_Gadget
       
        ;button events
        
        ;  /----------------------------------------------------------------\
        ;  |                    btn_send_email_min events                   |
        ;{ \----------------------------------------------------------------/ 
        If EventGadget() = btn_send_email_min
          
          gadget_id = btn_send_email_min 
          icon = icn_minimise
          
          Select EventType()
            Case #PB_EventType_MouseEnter
              form_control_button_over(gadget_id, $0000CC, icon)
      
            Case #PB_EventType_MouseLeave
              form_control_button_over(gadget_id, GBL_layer_border, icon)
      
            Case #PB_EventType_LeftButtonDown

            Case #PB_EventType_LeftButtonUp ; button up action
              form_control_button_over(gadget_id, GBL_layer_border, icon)
              SetWindowState(GetActiveWindow(), #PB_Window_Minimize)
      
          EndSelect
          ;}
          
          
        ;  /----------------------------------------------------------------\
        ;  |                   btn_send_email_close events                  |
        ;{ \----------------------------------------------------------------/ 

        ElseIf EventGadget() = btn_send_email_close
          
          gadget_id = btn_send_email_close
          icon = icn_close
          
          Select EventType()
            Case #PB_EventType_MouseEnter
              form_control_button_over(gadget_id, $0000CC, icon)
      
            Case #PB_EventType_MouseLeave
              form_control_button_over(gadget_id, GBL_layer_border, icon)
      
            Case #PB_EventType_LeftButtonDown
      
            Case #PB_EventType_LeftButtonUp ; button up action
              window_send_email_status = 1
               
          EndSelect
          
        EndIf  
        ;}
        
     EndSelect 
     
 Until window_send_email_status = 1
 
 DisableWindow(window_main, #False)
 StickyWindow(window_send_email, #False)
 CloseWindow(window_send_email)
 ; repaint the calling window
 RedrawWindow_(WindowID(window_main),#NUL,#NUL,#RDW_ALLCHILDREN|#RDW_INVALIDATE)
 SetActiveWindow(window_main)
 SetActiveGadget(-1) ; set no active gadget on active window

EndProcedure


Procedure send_emails(start_date)
  
  InitNetwork()

  If CreateMail(0, hex_decode(GBL_email_user), "")
    
    SetGadgetText(fld_send_email_status, "Composing email")
    
    SetMailAttribute(0, #PB_Mail_Subject, "Timesheet for approval")
    SetMailBody(0,  "A new timesheet has been submitted by " + hex_decode(GBL_forename) + "." + hex_decode(GBL_surname) + " for your approval." +  #CRLF$ + #CRLF$ + 
                    "This  timesheet is for the week begining " + FormatDate("%dd/%mm/%yyyy", start_date))
    
    SetGadgetText(fld_send_email_status, GetGadgetText(fld_send_email_status) + Chr(13) + "Getting email recipients")
    
    ; build the sql query
    ; this query gets all the email adressees
    GBL_sql = "SELECT "
    GBL_sql +   "email_user "
    GBL_sql + "FROM "
    GBL_sql +   "tbl_user "
    GBL_sql + "WHERE "
    GBL_sql +   "ets_approval = 1 "
    
    ; Execute a SQL query
    If DatabaseQuery(0, GBL_sql)
        
      While NextDatabaseRow(0)
        ; Change the recipients to real one
        recipient.s = GetDatabaseString(0, 0)
        AddMailRecipient(0, recipient, #PB_Mail_To)
        SetGadgetText(fld_send_email_status, GetGadgetText(fld_send_email_status) + Chr(13) + recipient)
      Wend
        
    Else
      window_warning("D A T A B A S E   E R R O R", GBL_sql + Chr(13) + Chr(13) + " This sql failed", "YES", window_send_email, 500) 
    EndIf
    
    Result = SendMail(0, "xxxx.xxxx.com", 25, 1, hex_decode(GBL_email_user), hex_decode(GBL_email_pass))
    
    SetGadgetText(fld_send_email_status, GetGadgetText(fld_send_email_status) + Chr(13) + "Sending email - Please wait...")
    
    
    direction = 0
    
    Repeat
      Progress = MailProgress(0)
      Delay(300)
      If direction = 0
        SetGadgetState(fld_send_email_progress, GetGadgetState(fld_send_email_progress) + 10)
        If GetGadgetState(fld_send_email_progress) = 100
          direction = 1
        EndIf
      Else
        SetGadgetState(fld_send_email_progress, GetGadgetState(fld_send_email_progress) - 10)
        If GetGadgetState(fld_send_email_progress) = 0
          direction = 0
        EndIf

      EndIf
      Progress = MailProgress(0)
      Delay(300)
      Select progress
        Case #PB_Mail_Connected ; The mail transfer is in its initialization phase.
          SetGadgetText(fld_send_email_status, GetGadgetText(fld_send_email_status) + Chr(13) + "Sending...")
        Case #PB_Mail_Finished ; The mail transfer is finished correctly.
          SetGadgetText(fld_send_email_status, GetGadgetText(fld_send_email_status) + Chr(13) + "Finished")
        Case #PB_Mail_Error
          SetGadgetText(fld_send_email_status, GetGadgetText(fld_send_email_status) + Chr(13) + " + + + E R R O R + + + ")
      EndSelect
        
    Until Progress = #PB_Mail_Finished Or Progress = #PB_Mail_Error
  
    If Progress = #PB_Mail_Finished
      SetGadgetText(fld_send_email_status, GetGadgetText(fld_send_email_status) + Chr(13) + "Mail correctly sent")
      SetGadgetText(fld_send_email_status, GetGadgetText(fld_send_email_status) + Chr(13) + "Updating time sheet status for selected week")
      ResetList(employee())               ; Reset the list index before the first element.
      
      GBL_sql = "UPDATE "
      GBL_sql +   "tbl_time_sheet "
      GBL_sql + "SET "
      GBL_sql +   "tbl_time_sheet.approved = 1 "
      GBL_sql + "WHERE "
      GBL_sql +   "tbl_time_sheet.project_day >= '" + FormatDate("%yyyy-%mm-%dd", start_date) + "' "
      GBL_sql +   "AND tbl_time_sheet.project_day <= '" + FormatDate("%yyyy-%mm-%dd", AddDate(start_date, #PB_Date_Day, 6 )) + "' "
      GBL_sql +   "AND tbl_time_sheet.user_name = '" + hex_decode(GBL_username) + "' "

	    ; Execute a SQL query
      If DatabaseQuery(0, GBL_sql)
        SetGadgetText(fld_send_email_status, GetGadgetText(fld_send_email_status) + Chr(13) + "Completed - refreshing display")
        get_user_open_projects(start_date)
      Else
        window_warning("D A T A B A S E   E R R O R", GBL_sql + Chr(13) + Chr(13) + " This sql failed", "YES", window_send_email, 500) 
      EndIf
    Else
      MessageRequester("Error", "Can't sent the mail !")
    EndIf
  
  EndIf
  
  window_send_email_status = 1
  
EndProcedure
User avatar
TI-994A
Addict
Addict
Posts: 2720
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Invalid memory access error

Post by TI-994A »

captain_skank wrote:...the email status window uses a thread to display the ongoing email status and it's this that seems to cause this invalid memory issue, because if i disable it and close the form manualy the main form doesn't thow the error and works as required.
Best guess; the thread is referencing a gadget that no longer exists. This means that the thread may be persisting after the window_send_email window has been closed.

Thus the IMA, instead of a gadget-not-initialised error. IMHO. :wink:
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
Post Reply