String manipulation gives Invalid Memory Access run time err

Just starting out? Need help? Post your questions and find answers here.
Steving
User
User
Posts: 13
Joined: Tue Sep 12, 2017 11:40 pm
Location: San Francisco Bay Area
Contact:

String manipulation gives Invalid Memory Access run time err

Post by Steving »

Hello all,

I'm sorry if this has been covered in another topic, I searched but there were a great many hits and it was hard sifting through them all. I'm having a problem with my code. It's a simple program to parse a log file and gather information together in a linked list and then export it to a CSV file. I'm getting an invalid memory access error when I try and populate the linked list structure with a substring. I've attached my code for reference below:

Dim InputParts$(6)
;Set DebugMode to 0 for none, 1 for screen (debug window), 2 for log file
;

#DebugMode = 2
#Q = #DQUOTE$
#QCQ = #DQUOTE$ + "," + #DQUOTE$

Structure FaxInfoStructure
StructureKey.l
MainFolder.s
DirectiveFile.s
FaxFile.s
SenderName.s
SenderCSID.s
RecipientName.s
RecipientCompany.s
RecipientFaxNumber.s
EmailNotification.s
Sent.i
Completed.i
ReturnString.s
ReturnJobID.s
EndStructure

NewList FaxInfo.FaxInfoStructure()

Procedure WriteDebugLine(DebugLine$)

If #DebugMode = 0
Debug DebugLine$
ElseIf #DebugMode = 2
WriteStringN(0, DebugLine$)
EndIf

EndProcedure

Procedure.s GetEnv(Variable$)

CompilerIf #PB_Compiler_OS = #PB_OS_Windows ; On Windows, use the API

Result$ = Space(1000)
If GetEnvironmentVariable_(@Variable$, @Result$, 1000)
ProcedureReturn Result$
Else
ProcedureReturn ""
EndIf

CompilerElse ; On Linux, use the environ array

Protected *Environ.LONG

!extrn _environ
!mov eax, [_environ]
!mov [esp+4], eax

Variable$ + "="

While *Environ\l <> 0
If CompareMemoryString(@Variable$, *Environ\l, 0, Len(Variable$)) = 0
ProcedureReturn PeekS(*Environ\l + Len(Variable$))
EndIf
*Environ + 4
Wend

ProcedureReturn ""
CompilerEndIf

EndProcedure

ReadFileName$ = OpenFileRequester("Select Log file to parse","","*.log;*.txt",0)
If ReadFileName$ = ""
MessageRequester("Exiting...","No file selected, ending program", #PB_MessageRequester_Ok)
End
EndIf

For x = Len(ReadFileName$) To 0 Step -1
If Mid(ReadFileName$,x,1) = "."
SuggestedSaveFile$ = Mid(ReadFileName$,0,x) + "csv"
Break
EndIf
Next x
FileSaveName$ = SaveFileRequester("Enter Output File",SuggestedSaveFile$,"*.csv",0)
If FileSaveName$ = ""
MessageRequester("Exiting...","No save file specified, ending program.", #PB_MessageRequester_Ok)
End
EndIf

If OpenWindow(0, 0, 0, 340, 50, "Parse Logs Progress", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
If CreateStatusBar(0, WindowID(0))
AddStatusBarField(120)
AddStatusBarField(170)
EndIf

StatusBarText(0,0,"File Read Progress:")
StatusBarProgress(0, 1, 0)

EndIf

TempLoc$ = GetEnv("TEMP")
LogFile$ = TempLoc$ + "\twco\ParseLogs_" + FormatDate("%yyyy%mm%dd%hh%ii%ss", Date()) + ".log"
If Not OpenFile(0, LogFile$, #PB_File_SharedWrite)
MessageRequester("Unable to open file", "Unable to open the log file for the program " + LogFile$ + ".", #PB_MessageRequester_Ok)
End 1
EndIf

FileTotalSize = FileSize(ReadFileName$)
If Not OpenFile(1, ReadFileName$, #PB_File_SharedRead)
MessageRequester("No File","Unable to open " + ReadFileName$, #PB_MessageRequester_Ok)
End 1
EndIf
ReadProgress = 0
ReadLineNumber = 0

While Eof(1) = 0
For x=1 To 6
InputParts$(x)=""
Next x

Input$ = ReadString(1)
ReadLineNumber = ReadLineNumber + 1
ReadProgress = ReadProgress + StringByteLength(Input$) / 2
ProgressToDisplay = Int((ReadProgress / FileTotalSize) * 100)
WriteDebugLine("Progress status: " + Str(ReadProgress) + " (raw) " + Str(ProgressToDisplay) + " (displayed)")

StatusBarProgress(0, 1, ProgressToDisplay)
Repeat:Until WindowEvent() = 0
WriteDebugLine("Processing Line: '" + Input$ + "'")
PartCount=1
BeenHereBefore=1 ; Set that in case the first character is a space, don't increment pointer
For x = 0 To Len(Input$)
If Mid(Input$,x,1) = " "
If Not BeenHereBefore
If PartCount < 6
PartCount = PartCount + 1
BeenHereBefore = 1
Else
InputParts$(PartCount) = InputParts$(PartCount) + Mid(Input$,x,1)
EndIf
EndIf
Else
InputParts$(PartCount) = InputParts$(PartCount) + Mid(Input$,x,1)
BeenHereBefore = 0
EndIf
Next x
If #DebugMode<>0
WriteDebugLine("Split String Follows:")
For x = 1 To 6
WriteDebugLine(Str(x) + " -- " + InputParts$(x))
Next x
EndIf
;
; Construct the key, which is the 3 digit code after the time followed by the number in slot 4
;
If InputParts$(4) <> #Empty$
FirstKey = Val(StringField(InputParts$(2), 2, ","))
LastKey = Val(InputParts$(4))
CompleteKey$ = Str(FirstKey)
For y = 2 To Len(Str(LastKey)) Step -1
CompleteKey$ = CompleteKey$ + "0"
Next y
Completekey$ = Completekey$ + Str(LastKey)
DebugLine$ = "Complete Key = " + CompleteKey$ + ", first part: " + FirstKey + ", second part: " + LastKey
WriteDebugLine(DebugLine$)
EndIf
KeyNumber=Val(CompleteKey$)

;
; Check if this key already exists. If it does, update it, if not, then create it
;

*Pointer = #Null
ResetList(FaxInfo())
If FirstElement(FaxInfo()) = 0
AddElement(FaxInfo())
*Pointer = @FaxInfo()
FaxInfo()\StructureKey = KeyNumber
Else
While NextElement(FaxInfo())
If FaxInfo()\StructureKey = KeyNumber
*Pointer = @FaxInfo()
EndIf
Wend
If Not *Pointer
AddElement(FaxInfo())
*Pointer = @FaxInfo
FaxInfo()\StructureKey = KeyNumber
EndIf
EndIf
;
; Now, add the appropriate fields
;
ResetList(FaxInfo())
ChangeCurrentElement(FaxInfo(), *Pointer)
If FindString(InputParts$(6),"main folder")
FaxInfo()\MainFolder = Mid(InputParts$(6), FindString(InputParts$(6), "main folder") + 12)
WriteDebugLine("Found main folder: '" + FaxInfo()\MainFolder + "'")
ElseIf FindString(InputParts$(6), "found control file")
FaxInfo()\DirectiveFile = Mid(InputParts$(6), FindString(InputParts$(6), "found control file") + 23)
WriteDebugLine("Found directive file: '" + FaxInfo()\DirectiveFile + "'")
ElseIf FindString(InputParts$(6), "Adding filename")
FaxInfo()\FaxFile = Mid(InputParts$(6), FindString(Inputparts$(6), "Adding filename") + 17)
WriteDebugLine("Found Fax file (or one of them): '" + FaxInfo()\FaxFile + "'")
ElseIf FindString(InputParts$(6), "SenderName")
FaxInfo()\SenderName = Mid(InputParts$(6), FindString(InputParts$(6), ":") + 2)
WriteDebugLine("Found Sender Name: '" + FaxInfo()\SenderName + "'")
ElseIf FindString(InputParts$(6), "SenderCSID")
FaxInfo()\SenderCSID = Mid(InputParts$(6), FindString(InputParts$(6), ":") + 2)
WriteDebugLine("Found Sender CSID: '" + FaxInfo()\SenderCSID)
ElseIf FindString(InputParts$(6), "RecipientName")
FaxInfo()\RecipientName = Mid(InputParts$(6), FindString(InputParts$(6), ":") + 2)
WriteDebugLine("Found Recipient Name: '" + FaxInfo()\RecipientName + "'")
ElseIf FindString(InputParts$(6), "FaxNumber")
FaxInfo()\RecipientFaxNumber = Mid(InputParts$(6), FindString(InputParts$(6), ":") + 2)
WriteDebugLine("Found Recipient Fax Number '" + FaxInfo()\RecipientFaxNumber + "'")
ElseIf FindString(InputParts$(6), "RecipientCompany")
FaxInfo()\RecipientCompany = Mid(InputParts$(6), FindString(InputParts$(6), ":") + 2)
WriteDebugLine("Found Recipient Company: '" + FaxInfo()\RecipientCompany + "'")
ElseIf FindString(InputParts$(6), "EmailNotificationAddress")
FaxInfo()\EmailNotification = Mid(InputParts$(6), FindString(InputParts$(6), ":") + 2)
WriteDebugLine("Found E-mail notification address: '" + FaxInfo()\EmailNotification + "'")
ElseIf FindString(InputParts$(6), "Returned JobId")
FaxInfo()\ReturnJobID = Mid(InputParts$(6), FindString(InputParts$(6), ":") + 2)
WriteDebugLine("Found the Returned Job ID: '" + FaxInfo()\ReturnJobID)
ElseIf FindString(InputParts$(6), "Return String")
DebugLine$ = InputParts$(6) + "---" + Str(FindString(InputParts$(6),"Return String")) + "_>_>_>" + Str(ReadLineNumber) + " String Length: (" + Str(Len(InputParts$(6))) + ")"
Debug DebugLine$
Debug Mid(InputParts$(6), FindString(InputParts$(6), "Return String") + 16)
FaxInfo()\ReturnString = Mid(InputParts$(6), FindString(InputParts$(6), "Return String") + 16)
WriteDebugLine("Found Reurned String: '" + FaxInfo()\ReturnString + "'")
If FindString(InputParts$(6),"Successfully")
FaxInfo()\Sent = 1
WriteDebugLine("Fax was successfully sent!")
EndIf
EndIf

Wend
CloseFile(1)

OpenFile(2,FileSaveName$)
WriteStringN(2,#Q + "Concord Process #" + #QCQ + "Main Folder" + #QCQ + "Directive File Name" + #QCQ + "Fax File Name" + #QCQ + "Sender Name" + #QCQ + "Sender CSID" + #QCQ + "Recipient Name" + #QCQ + "Recipient Company" + #QCQ + "Recipient Fax Number" + #QCQ + "E-mail Notification address" + #QCQ + "Sent?" + #QCQ + "Completed?" + #QCQ + "Return String from Concord" + #QCQ + "Concord Job ID" + #Q)

ForEach FaxInfo()
*Pointer = @FaxInfo
WriteDebugLine("--------------------------------------")
WriteDebugLine(Str(*Pointer))
WriteDebugLine(" Structure Key: " + FaxInfo()\StructureKey)
WriteDebugLine(" Main Folder: " + FaxInfo()\MainFolder)
WriteDebugLine(" Directive File: " + FaxInfo()\DirectiveFile)
WriteDebugLine(" Fax file: " + FaxInfo()\FaxFile)
WriteDebugLine(" Sender Name: " + FaxInfo()\SenderName)
WriteDebugLine(" Sender CSID: " + FaxInfo()\SenderCSID)
WriteDebugLine(" RecipientName: " + FaxInfo()\RecipientName)
WriteDebugLine(" RecipientCompany:" + FaxInfo()\RecipientCompany)
WriteDebugLine(" Recipient Fax: " + FaxInfo()\RecipientFaxNumber)
WriteDebugLine(" Email Notify: " + FaxInfo()\EmailNotification)
WriteDebugLine(" Sent? " + FaxInfo()\Sent)
WriteDebugLine(" Completed? " + FaxInfo()\Completed)
WriteDebugLine(" Return String: " + FaxInfo()\ReturnString)
WriteDebugLine(" Return Job ID: " + FaxInfo()\ReturnJobID)
WriteString(2,#Q + FaxInfo()\StructureKey + #QCQ + FaxInfo()\MainFolder + #QCQ + FaxInfo()\DirectiveFile + #QCQ + FaxInfo()\FaxFile + #QCQ + FaxInfo()\SenderName + #QCQ + FaxInfo()\SenderCSID + #QCQ + FaxInfo()\RecipientName + #QCQ + FaxInfo()\RecipientCompany + #QCQ + FaxInfo()\RecipientFaxNumber + #QCQ + FaxInfo()\EmailNotification + #QCQ)
If FaxInfo()\Sent
WriteString(2,"Yes" + #QCQ)
Else
WriteString(2,"No" + #QCQ)
EndIf
If FaxInfo()\Completed
WriteString(2,"Yes" + #QCQ)
Else
WriteString(2,"No" + #QCQ)
EndIf
WriteStringN(2,FaxInfo()\ReturnString + #QCQ + FaxInfo()\ReturnJobID + #Q)
Next


The error occurs on the highlighted line. If anyone can point me in the right direction that would be great.

Thanks so much,

steving
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: String manipulation gives Invalid Memory Access run time

Post by Demivec »

Two lines appear to contain a typo. They are lines 186 and 244 and they are identical. They read:

Code: Select all

;line as entered 
*Pointer = @FaxInfo

;should instead be
*Pointer = @FaxInfo()

Using EnableExplicit would help catch such typos (and you would have to declare your variables).
normeus
Enthusiast
Enthusiast
Posts: 471
Joined: Fri Apr 20, 2012 8:09 pm
Contact:

Re: String manipulation gives Invalid Memory Access run time

Post by normeus »

use {code} {/code} style so that people read your code.

use

Code: Select all

GetTemporaryDirectory()
to get location of temp folder.

sample data would be nice.
I tried some random text data and didn't get an error so it might be your input file.
this is the debug output from my test file
[17:29:10] 4469092
[17:29:10] Structure Key: 210
[17:29:10] Main Folder:
[17:29:10] Directive File:
[17:29:10] Fax file:
[17:29:10] Sender Name:
[17:29:10] Sender CSID:
[17:29:10] RecipientName:
[17:29:10] RecipientCompany:
[17:29:10] Recipient Fax:
[17:29:10] Email Notify:
[17:29:10] Sent? 0
[17:29:10] Completed? 0
[17:29:10] Return String:
[17:29:10] Return Job ID:
[17:29:10] --------------------------------------
[17:29:10] 4469092
[17:29:10] Structure Key: 212
[17:29:10] Main Folder:
[17:29:10] Directive File:
[17:29:10] Fax file:
[17:29:10] Sender Name:
[17:29:10] Sender CSID:
[17:29:10] RecipientName:
[17:29:10] RecipientCompany:
[17:29:10] Recipient Fax:
[17:29:10] Email Notify:
[17:29:10] Sent? 0
[17:29:10] Completed? 0
[17:29:10] Return String:
[17:29:10] Return Job ID:
[17:29:10] --------------------------------------
[17:29:10] 4469092
[17:29:10] Structure Key: 312
[17:29:10] Main Folder:
[17:29:10] Directive File:
[17:29:10] Fax file:
[17:29:10] Sender Name:
[17:29:10] Sender CSID:
[17:29:10] RecipientName:
[17:29:10] RecipientCompany:
[17:29:10] Recipient Fax:
[17:29:10] Email Notify:
[17:29:10] Sent? 0
[17:29:10] Completed? 0
[17:29:10] Return String:
[17:29:10] Return Job ID:
this is a sample of your log file:
6 --
Progress status: 20542 (raw) 66 (displayed)
Processing Line: 'Used French Fry Oil Fuels London Offices as Buildings Go Green'
Split String Follows:
1 -- UUsed
2 -- French
3 -- Fry
4 -- Oil
5 -- Fuels
6 -- London Offices as Buildings Go Green
Complete Key = 0000, first part: 0, second part: 0
Progress status: 20542 (raw) 66 (displayed)
Processing Line: ''
Split String Follows:
1 --
2 --
3 --
4 --
5 --
6 --
Progress s
and also follow @Demivec advice

Norm
google Translate;Makes my jokes fall flat- Fait mes blagues tombent à plat- Machte meine Witze verpuffen- Eh cumpari ci vo sunari
Steving
User
User
Posts: 13
Joined: Tue Sep 12, 2017 11:40 pm
Location: San Francisco Bay Area
Contact:

Re: String manipulation gives Invalid Memory Access run time

Post by Steving »

I'm sorry I didn't use the code "code" to put in my code :oops:

My code dies the first time it hits a line in the input file that qualifies to be edited out for the "Return String" ElseIf part of the code, around line 229. I put in a check to see if I'm bounding off the end of the string by checking the length of the string vs. the positing of the found string "Return String" and it gives me what I believe is a false positive indicating that the actual location of the string was greater than the length. However, I don't believe it's my string manipulation that is at issues based on this information:
'Successfully submitted fax. Return String: Success TimeToFreePort: 0'---Position of 'Return String' text: 29. Line number in input file: 19933 String Length: (68)
Success TimeToFreePort: 0
That comes from this substructure of the code:

Code: Select all

ElseIf FindString(InputParts$(6), "Return String")
    DebugLine$ = "'" + InputParts$(6) + "'---Position of 'Return String' text: " + Str(FindString(InputParts$(6),"Return String")) + ".  Line number in input file: " + Str(ReadLineNumber) + "  String Length: (" + Str(Len(InputParts$(6))) + ")"
    Debug DebugLine$
    Debug Mid(InputParts$(6), FindString(InputParts$(6), "Return String") + 15)
    FaxInfo()\ReturnString = Mid(InputParts$(6), FindString(InputParts$(6), "Return String") + 15)
    WriteDebugLine("Found Reurned String: '" + FaxInfo()\ReturnString + "'")
    If FindString(InputParts$(6),"Successfully") 
      FaxInfo()\Sent = 1
      WriteDebugLine("Fax was successfully sent!")
    EndIf
  EndIf
The code was working when I was using a StringField portion of code rather than the loop to get my data extracted, but due to inconsistencies in the data the StringField command wasn't extracting the data correctly. I may have never got to this portion of code before, but it pretty much matches with the other sections of code above it that are working. I'm sorry that I can't be more specific, I'm a newbie to PureBasic but I'm loving it so far albiet for this error, that is probably somehow coded incorrectly. I'm thinking it has something to do with my linked list and structure, but I'm not familiar enough with the language to identify what it is. It all looks OK to me. As you can see by the line number of the error the code gets all the way down to reading line 19,933 before getting the error. And, judging by my log file the system extracts other data from the input string.
Complete Key = 842006, first part: 842, second part: 6
Progress status: 3329 (raw) 0 (displayed)
Processing Line: '2017-07-03 01:00:28,842 INFO 6 [MessageStoreFactory] SenderCSID: 19256066978'
Split String Follows:
1 -- 22017-07-03
2 -- 01:00:28,842
3 -- INFO
4 -- 6
5 -- [MessageStoreFactory]
6 -- SenderCSID: 19256066978
Complete Key = 842006, first part: 842, second part: 6
Found Sender CSID: '19256066978
So, it puts that stuff away but not the other stuff. I'm racking my brain but I can't figure out what's wrong. Any help you all have is much appreciated.

Here is the line that kills it:
2017-07-03 01:02:32,356 INFO 9 [WebServiceMessage] Successfully submitted fax. Return String: Success TimeToFreePort: 0
Sincerely,

Steving
Steving
User
User
Posts: 13
Joined: Tue Sep 12, 2017 11:40 pm
Location: San Francisco Bay Area
Contact:

Re: String manipulation gives Invalid Memory Access run time

Post by Steving »

:idea: :arrow: :mrgreen:

Update:

Thanks so much Demivec for your suggestion of using Option Explicit. I fixed one of the typo's with the Pointer without the () but I missed another one. However, Option Explicit found it for me and now I'm fat dumb and happy (or at least fat and dumb).

Thanks everyone for your help. I think I'm rolling again now.

Sincerely,

Steving
Post Reply