[Solved] Memory Leak

4 posts in this topic

#1 ·  Posted (edited)

I'm basically processing text files where I'm reading them from a disk file into an input array, going through the input array and skipping what I don't want and writing it out to an output array and then writing the output array to a disk file.  I encountered an "Error allocating memory" message.  I have stripped down the program to illustrate how the memory usage grows in a looping routine (__ReadFiles).  I have tried a _ReduceMemory routine (from https://www.autoitscript.com/forum/topic/134831-is-there-a-way-to-free-up-memory-being-used/ ) and it helps somewhat, however the peak working set continues to grow regardless.  I believe I'm releasing resources (resetting arrays to 0) and am trying to figure out if the leak is from FileFindNextFile or something else I'm doing.   To illustrate the program creates a subdirectory with 50000 simple text files and then runs showing the growing memory usage, Ctrl+q will pause program.  Rerunning the program uses the already created files so it does not have to be re-created.  Any help appreciated.

; use this to debug in console window <--- LOOK

#include <Array.au3>
#include <File.au3>
#include <MsgBoxConstants.au3>
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>

HotKeySet ( "^q", "EndProgram" )    ;v2e - added HotKeySet ( "^q", "EndProgram" ); CTRL+q so can pause/exit script

Global $hEdit   ;for scrolling text box

Global $textarray[1]    ;1 element
$textarray[0] = 0       ;initial count
Global $newtextarray[1] ;1 element
$newtextarray[0] = 0    ;initial count

Global $dir
Global $k       ;loop count

Global $aMemory ;v1g    for use in __ShowMemoryUsage("Location: In FileFindNextFile While 1 loop.")

Global $debug = 0       ;0=off, 1=on , 2=deeper,  - use debug > 1 to see arrays in Funcs

$version = "v1g"
;v1g - we have an Autoit "Error allocating memory" somewhere - printing out WorkingSetSize and  PeakWorkingSetSize from ProcessGetStats to try and find it

__scrolling_text_box_init("--- Read files ---", 1050, 450)  ;__scrolling_text_box_init($title, $width, $height)     ;set up box - to display text use: __scrolltext($text)
WinMove("--- Read files ---", "", 2000, 300)    ;move so can see it - on single screen use  10, 30 on dual screen use 2000, 300
__scrolltext("Starting:  " & @CRLF)

;illustrate error using current script directory by creating unique directotry and create file in it and put some text into it -----------
$dir = @ScriptDir

;for iterative testing see if test directory already exists - i.e. only need to build this once
$dir = @ScriptDir & "\testdir_xcrgua"   ;highly unlikely areadly exists unless this program was already run
$str = ""   ;null it
For $j = 1 to 100   ;put 100 lines in each file
    $str = $str & $j & @CRLF

If DirGetSize($dir) = -1 Then
    DirCreate($dir) ;create directory   ;then create and fill it
    For $i = 1 to 50000     ;brute force (and I know it's slow, however straightforward and only 1 time
        FileWrite($dir & "\" & $i & ".txt", $str)
        If $i/1000 = Int($i/1000) Then __scrolltext("Writing test file " & $i & "/50000" & @CRLF)
MsgBox(262144, "DEBUG", $dir & "  <-- should have 50000 files each with 100 numbered lines 1- 100.")

MsgBox(262144, "DEBUG", "Paused.")

__scrolltext("Reading files in dir = " & $dir & @CRLF)
;__ShowMemoryUsage("Location: Before file count.")  ;v1g
$fc = __GetFileCount($dir)  ;returns file count in $dir
;__ShowMemoryUsage("Location: After file count.")   ;v1g
__scrolltext("Number of files in dir = " & $fc & @CRLF)
MsgBox(262144, "DEBUG", "Paused.")

;in this we get memory allocation erroroccurs between 25K and 50K on my machine

MsgBox(262144, "DEBUG", "Paused out of loop.")


;----------------------------------- Functions -----------------------------------

Func    __ShowMemoryUsage($title)

        $aMemory = ProcessGetStats()    ; Retrieve memory details about the current process.

        ; If $aMemory is an array then display the following details about the process.
        If IsArray($aMemory) Then
            __scrolltext($title & "   " & "WorkingSetSize: " & $aMemory[0] & "      PeakWorkingSetSize: " & $aMemory[1] & @CRLF)
            __scrolltext("An error occurred in ProcessGetStats() in Func __ShowMemoryUsage($title).")

EndFunc     ;__ShowMemoryUsage($title)

Func _ReduceMemory($i_PID = -1) ;from https://www.autoitscript.com/forum/topic/134831-is-there-a-way-to-free-up-memory-being-used/
    If $i_PID <> -1 Then
        Local $ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1F0FFF, 'int', False, 'int', $i_PID)
        Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', $ai_Handle[0])
        DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $ai_Handle[0])
        Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', -1)
    Return $ai_Return[0]
EndFunc   ;==>_ReduceMemory

Func    __GetFileCount($dir)    ;returns number of files in $dir - brute force but only about 50K files/directory

    ;MsgBox(0, "DEBUG", "$dir = '" & $dir & "'")

    $fcount = 0     ;init count
    $search = FileFindFirstFile($dir & "\*.*")

    If $search = -1 Then    ;no files found
        ;MsgBox(0, "Error", "No files/directories matched the search pattern")

    ;okay check number of files
    While 1
        $file = FileFindNextFile($search)
        If @error Then
            ExitLoop        ;exit loop when there are no more files
            $fcount = $fcount + 1

    FileClose($search)  ;be polite




Func    __ReadFiles($dir)   ;just reading to show memory alloc error

    Local $x
    Local $skipline

    $tfc = __GetFileCount($dir) ;get total file count so we can show progress

    $cfc = 0    ;init currect file count
    $search = FileFindFirstFile($dir & "\*.*")  ;get search handle

    If $search = -1 Then    ;no files found
        __scrolltext("Working on file: " & $cfc & "/" & $tfc & @CRLF)
        ;MsgBox(0, "Error", "No files/directories matched the search pattern")

    ;okay go through the files one by one
    While 1

        ;_ReduceMemory()    ;this makes little difference - surprising

        $file = FileFindNextFile($search)
        If @error = 1 Then ExitLoop     ;exit loop when there are no more to do
        If @extended = 1 Then
            $adir = 1   ;we have a directory so note it
            $adir = 0   ;a file

        ;MsgBox(4096, "File:", $directory&"\"&$file)
        $cfc = $cfc + 1
        __scrolltext("Working on file: " & $cfc & "/" & $tfc & "     " & $file & @CRLF) ;show the filename

        __ShowMemoryUsage("Location: In FileFindNextFile While 1 loop.")    ;v1g

        ;clear out arrays so we have no artifacts from procesing the prior loop
        ;from here it looks like resetting it is better https://www.autoitscript.com/forum/topic/110933-solved-how-to-delete-whole-array/
        $testarray = 0
        $newtextarray = 0

        Dim $textarray[1]       ;1 element
        $textarray[0] = 0       ;initial count
        Dim $newtextarray[1]    ;1 element
        $newtextarray[0] = 0    ;initial count

        ;bring file into memory for faster processing
        If $adir = 0 Then   ;process file
            $x = _FileReadToArray($dir & "\" & $file, $textarray)       ;bring file into memory for faster processing [0] has $textarray count
            If $x <> 1 Then
                MsgBox($MB_TOPMOST + $MB_ICONERROR, "ERROR", "Unable to read file into array.  Error = " & $x & "    @error = " & @error & "    @extended = " & @extended)
            If $debug > 0 Then _ArrayDisplay($textarray, "INPUT $textarray")

            ReDim $newtextarray[$textarray[0] + 1]  ;create output array ($newtextarray) of the same size as input array ($textarray) and later ReDim the output array to the correct size
            $newtextarray[0] = 0        ;set the count of actual entries as $newtextarray is empty but has same size as $textarray
            If $debug > 0 Then _ArrayDisplay($newtextarray, "Starting $newtextarray")

            ;now the approach is to write out only lines we want then to file
            For $i = 1 to $textarray[0] ;process all elements (rows, lines) in input array
                ;If $debug > 0 Then __scrolltext("$textarray[" & $i & "] = '" & $textarray[$i] & "'" & @CRLF)   ;show the line
                $skipline = 0   ;init value to not skip line
                ;----------- start stripping out stuff -----------
                ;this rountine is not the cause of the memory leak so removed
                If $skipline = 0 Then   ;write it out
                    $newtextarray[0] = $newtextarray[0] + 1     ;increase count and point to index where we're going to store it in $newtextarray
                    $newtextarray[$newtextarray[0]] = $textarray[$i]
                    ;skip the line

            $fn = $dir & "\processed-1\" & StringLeft($file, StringLen($file) - 4) & "-1.txt"

            __scrolltext("Processed file written to: " &$fn & @CRLF)    ;show the line
            ;RECALL written out like an array so 1st entry which corresponds to index [0] has count of rows = lines in the file
        Else    ;its a directory - skip it
            __scrolltext("NOT processed directory (i.e. skipped) : " & $dir & "\" & $file & @CRLF)  ;show the line


EndFunc ;__CleanFiles($dir)

Func __scrolling_text_box_init($title, $width, $height)
    ;from http://www.autoitscript.com/forum/topic/110948-add-text-to-edit-box-and-scroll-it-down/page__p__971158__hl___guictrledit_scroll__fromsearch__1#entry971158

    $hGUI = GUICreate($title, $width, $height)
    $hEdit = GUICtrlCreateEdit("", 10, 10, $width-20, $height-20, BitOr($GUI_SS_DEFAULT_EDIT, $ES_READONLY))
    ;$limit = 9223372036854775807   ;2^63
    $limit = 1000000000 ;works
    $x = GUICtrlSetLimit($hEdit, $limit)
    ;~ If $x = 0 Then
    ;~  MsgBox(0, "ERROR", "Limit of " &  $limit & " is too large.")
    ;~ Else
    ;~  MsgBox(0, "Okay", "Limit of " &  $limit & " is okay.")
    ;~ EndIf

    ;$hButton = GUICtrlCreateButton("Add", 10, 250, 80, 30)



Func __scrolltext($text)
    ;prefix everything with date and time e.g. 2014-02-01 HH:MM:SS
    $dt = @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & "  "
    $text = $dt & $text
    GUICtrlSetData($hEdit, $text, 1)

Func EndProgram()
    $x = MsgBox($MB_TOPMOST + $MB_YESNO + $MB_ICONWARNING, "Paused", "Do you want to continue?")
    If $x = $IDNO Then
        Exit    ;exit program
        ;just a pause - so continue


04 - Clean files - v1g - test for memory leak v1c.au3

Edited by ahha
Added as a file.

Share this post

Link to post
Share on other sites

Hi ahha

This is the line in your __scrolltext() function that is using all your memory.

GUICtrlSetData($hEdit, $text,1)

It's appending to the existing contents of the control each time it is executed. If you change it to this your memory problems will disappear.

GUICtrlSetData($hEdit, $text)


1 person likes this

"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook

Share this post

Link to post
Share on other sites

#3 ·  Posted (edited)


Thanks - I totally missed that - duh - I feel stupid.:'(  I do have a question however.  Why when using scrolling text does the PeakWorkingSetSize increase but not the WorkingSetSize.  I would have thought the WorkingSetSize would increase if the text is being stored/displayed. I've forgotten how to indicate solved at the topic top.

Edited by ahha

Share this post

Link to post
Share on other sites
On 2/1/2016 at 7:44 PM, ahha said:


Thanks - I totally missed that - duh - I feel stupid.:'(  I do have a question however.  Why when using scrolling text does the PeakWorkingSetSize increase but not the WorkingSetSize.  I would have thought the WorkingSetSize would increase if the text is being stored/displayed. I've forgotten how to indicate solved at the topic top.

Edit your original post and change the title to [Solved] Memory Leak

False Positive Reporter - Mass email all anti virus vendors with an attachment of your program for fast and easy whitelisting.

PortableApps.com App Creation Wizard  - A simple GUI-based Wizard for creating PortableApps.

SoundBoard - Play any song or sound you want at the press of a hotkey.

My GitHub Page: https://github.com/BetaLeaf

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • Jibberish
      By Jibberish
      I am trying to add data to an array and I keep getting the error "Subscript used on non-accessible variable ".
      #include <array.au3> ; Includes, etc ~ ~ ~ Local $aOptionsArray[3] $aOptionsArray = CheckboxesAndRadioButtons() _ArrayDisplay($aOptionsArray) Func CheckboxesAndRadioButtons() ; Create Checkboxes and Radio Buttons and read the results ~ ~ ~ ; Radio Buttons to Array ; $aOptions[0] = $bTestSelectForever ; $aOptions[1] = $bTestSelect3Times ; $aOptions[2] = $bTestSelectOnce If $bSelect1 = 1 Then $aOptions[0] = "True" Else $aOptions[0] = "False" <<< This is where the error occurs. EndIf If $bSelect2 = 1 Then $aOptions[1] = "True" Else $aOptions[1] = "False" EndIf If $bSelect3 = 1 Then $aOptions[2] = "True" Else $aOptions[2] = "False" EndIf Return $aOptions EndFunc Is putting data into an array while in a If - Then - Else illegal?
    • anoig
      By anoig
      Hi all, 

      First, I want to give a huge shout-out to the community. I'm completely self-taught, and have never had to actually ask a question before because the forum is that good at answering questions and explaining things. However, I'm kind of stumped here, and I've been stuck on this problem for almost a full day.

      I'm working on a script to populate drafts of deeds at work. I have the main GUI and  a function (ctrl($n) and read()) for adding fields to find and data to replace it with to an array for later use with _word_docfindreplace. All of that works. However, due to the way I have the forms set up, I need to create additional fields and info based on the data that's there. Specifically, if there's only one buyer, I need to add the field [Buyer1&2] and the data in $aArray_Base for [Buyer 1]. I also need to add a field [Buyer 2] and have a blank data set in the next column over in the array, and I need to do the same for the Seller. To this end, the function parties() sets boolean variables $2buyers and $2sellers accordingly. Then, I have buyers() and sellers() to populate the data. 

      The problem that I'm running into is that each function works... when ONLY the buyer 1 name field is filled, and when ONLY the seller 1 field is filled.

      So if I fill Buyer 1 Name and save it, the data is populated correctly. But when I fill Buyer 1 and Seller 1 name, only the buyer 1 data populates correctly. Worse, when I fill several fields, neither populate correctly. I have no idea why this happens. I've added messageboxes to debug throughout the entire process and can't pinpoint what's causing the issue. The entire script is below. The function(s) in question are buyers() and sellers(). Only Sellers() has messageboxes throughout.

      Can someone help walk me through what might be causing this and help me find a solution? Thanks a ton in advance, and sorry for the wall of text.
    • InunoTaishou
      By InunoTaishou
      Cleaning up some old folders and found this little snippit. Think I was using this back when I was trying to create 2d maps for a game I was making in GDI+ (that never got finished). Pretty straight forward, searches an array for an array.
      #include <Array.Au3> Search() Func Search() Local $aArrayToFind[][] = [["V", "V", "V", "V", "V"], ["V", "V", "V", "V", "V"], ["V", "V", "V", "V", "B"], ["V", "V", "V", "V", "B"], ["V", "V", "V", "V", "B"]] Local $aArrayToSearch[][] = [["R", "R", "R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "X", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "X", "V", "V", "V", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "X", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "X", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "V", "V", "V", "V", "V", "T", "T", "T", "T", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "X", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "B", "B", "B", "B", "B", "B", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "B", "B", "B", "B", "B", "B", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "X", "V", "V", "V", "X", "B", "B", "B", "B", "B", "V", "V", "V", "V", "B", "B", "B", "B", "B", "B", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "V", "V", "V", "V", "V", "B", "B", "B", "B", "B", "V", "V", "V", "X", "V", "V", "B", "D", "B", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "X", "V", "V", "V", "X", "B", "D", "B", "B", "B", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "V", "V", "V", "V", "V", "V", "V", "V", "X", "X", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "X", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "R", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "V", "V", "V", "X", "T", "T", "T", "T", "T", "T", "T", "T", "X", "X", "V", "V", "V", "V", "V", "V", "V", "V", "V", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "T", "T", "T", "T", "T", "T"], _ ["V", "V", "V", "V", "V", "V", "V", "V", "V", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "V", "X", "V", "V", "X", "B", "B", "B", "B", "B", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "B", "B", "B", "B", "B", "V", "V", "V", "V", "V", "M", "M", "M", "M", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "X", "B", "D", "B", "B", "B", "V", "V", "V", "V", "V", "M", "M", "M", "M", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "M", "M", "D", "M", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "C", "C", "C", "C", "C", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "V", "T", "T", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "C", "C", "C", "C", "C", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "V", "T", "T", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "C", "C", "C", "C", "C", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "W", "W", "W", "W", "W", "W", "V", "V", "V", "V", "V", "V", "V", "C", "C", "D", "C", "C", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "W", "W", "W", "W", "W", "W", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "W", "W", "W", "W", "W", "W", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "W", "W", "W", "W", "W", "W", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "L", "L", "L", "L", "W", "W", "W", "W", "W", "W", "L", "L", "L", "V", "V", "V", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "X", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "R", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T"], _ ["R", "R", "R", "R", "R", "R", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "V", "V", "V", "V", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T", "T"]] Local $aArrayInArray = ArrayInArray($aArrayToSearch, $aArrayToFind) If (@Error) Then MsgBox("", "Error", "Error doing search: " & @Error) Else If ($aArrayInArray[0] = 1) Then ToolTip("Start Coords = " & $aArrayInArray[1] & ", " & $aArrayInArray[2] & @LF & _ "End Coords = " & $aArrayInArray[1] + UBound($aArrayToFind, $UBOUND_ROWS) - 1 & ", " & $aArrayInArray[2] + UBound($aArrayToFind, $UBOUND_COLUMNS) - 1 & @LF & _ "(Approx) Center coords = " & $aArrayInArray[1] + Int(UBound($aArrayToFind, $UBOUND_ROWS) / 2) & ", " & $aArrayInArray[2] + Int(UBound($aArrayToFind, $UBOUND_COLUMNS) / 2), 0, 0) $aArrayToSearch[$aArrayInArray[1]][$aArrayInArray[2]] = "Start" $aArrayToSearch[$aArrayInArray[1] + UBound($aArrayToFind, $UBOUND_ROWS) - 1][$aArrayInArray[2] + UBound($aArrayToFind, $UBOUND_COLUMNS) - 1] = "End" $aArrayToSearch[$aArrayInArray[1] + Int(UBound($aArrayToFind, $UBOUND_ROWS) / 2)][$aArrayInArray[2] + Int(UBound($aArrayToFind, $UBOUND_COLUMNS) / 2)] = "(Approx) Center" _ArrayDisplay($aArrayToSearch, "ArrayInArray") ElseIf ($aArrayInArray[0] > 1) Then MsgBox("", "Multiple Matches", "Multiple Matches Found For Search") Else MsgBox("", "No Matches", "No Matches Found For Search") EndIf EndIf EndFunc ;==>Start Func ArrayInArray($aArrayToSearch, $aArrayToFind) Local $aReturn[3] = [0, -1, -1] If (Not IsArray($aArrayToSearch)) Then Return SetError(1, 0, $aReturn) If (Not IsArray($aArrayToFind)) Then Return SetError(2, 0, $aReturn) Local $iRowsToSearch = UBound($aArrayToSearch, $UBOUND_ROWS) Local $iColumnsToSearch = UBound($aArrayToSearch, $UBOUND_COLUMNS) Local $iRowsToFind = UBound($aArrayToFind, $UBOUND_ROWS) Local $iColumnsToFind = UBound($aArrayToFind, $UBOUND_COLUMNS) If ($iRowsToFind > $iRowsToSearch) Then Return SetError(3, 0, $aReturn) If ($iColumnsToFind > $iColumnsToSearch) Then Return SetError(4, 0, $aReturn) For $iRow = 0 To $iRowsToSearch - $iRowsToFind For $iColumn = 0 To $iColumnsToSearch - $iColumnsToFind Local $bValid = False For $i = 0 To $iRowsToFind - 1 For $p = 0 To $iColumnsToFind - 1 If ($aArrayToFind[$i][$p] = "" Or $aArrayToFind[$i][$p] = $aArrayToSearch[$iRow + $i][$iColumn + $p]) Then $bValid = True Else $bValid = False ExitLoop 2 EndIf Next Next If ($bValid) Then ; Number of valid results found $aReturn[0] += 1 ; row of the last valid result found $aReturn[1] = $iRow ; column of the last valid result found $aReturn[2] = $iColumn EndIf Next Next Return $aReturn EndFunc ;==>ArrayInArray ArrayInArray Returns an array: [0] = number of results found, [1] = row of the last valid result found, [2] = column of the last valid result found
    • distancesprinter
      By distancesprinter
      _ArrayDisplay($aArray, "Window Title", "1:", 0, Default, "Column") ; Expected results are rows 1 to the end of the array, all columns. The result is rows 0-1, all columns. The API reference is here:
      Am I doing something wrong?
    • LoneWolf_2106
      By LoneWolf_2106
      Hi everybody,
      i have a question related to strings items in an Array and sorting. Maybe someone can advice me how to solve the issue.
      I have an Array of strings, every item of the Array is as following:
      INFO [13.06.2017 11:48:01] [Thread-13] [ConGenImpUsb -> waitForConnection]  INFO [07.06.2017 08:55:44] [main] MDU5 - Ver 5.1x I want to sort the item in the array by date and time, is there any function which allows me to sort by date/time?
      Thanks in advance