Memory Allocate Crash?

Just starting out? Need help? Post your questions and find answers here.
benco5000
User
User
Posts: 13
Joined: Mon Mar 01, 2010 8:56 pm

Memory Allocate Crash?

Post by benco5000 »

Ok. I've been hammering on this for a couple of weeks now. This is a subsection of one of my programs. What its supposed to do is escape Hyphens (referred to as ticks in the program) and turn a single into a double tick. All this is performed in memory. I am unable to get much consistency out of the error, other than, if I select about 10 or 20 files, it will crash on one of the pointers, the memory allocation, or debug output on a memory pointer. You can put any set of files through it. It should just read the bytes and expand single ticks (') to double ticks ('') in memory and exit.

I would appreciate if anyone having some spare time would take a look and see if they are able to duplicate the error.

TIA.

Here it is.

Code: Select all

Procedure.i CountTicks(*StringBuffer)                                           ;; count the ticks
  tickCount = 0                                                                 ;; init tick count
  fileLength = MemorySize(*StringBuffer)                                        ;; get the file length
  For c = 1 To fileLength                                                       ;; iterate through the file
    *thisChar = *StringBuffer + c                                               ;; look at each character
    If PeekB(*thisChar) = 39                                                    ;; if its a tickmark
      tickCount = tickCount + 1                                                 ;; count it
    EndIf                                                                       ;; end if its a tickmark
  Next                                                                          ;; next character
  ProcedureReturn (tickCount)                                                   ;; done retun the count
EndProcedure


;----------------------------------------------
; open a directory window
; select file or types
;----------------------------------------------
Title$ = "Select files to import."                                            ;; Title for window
DefaultFile$ = ""                                                             ;; No default file
;Pattern$ =  "All Files (*.sql,*.txt)|*.sql;*.txt|" +                          ;; the pattern to pass the filter box
;_  "SQL Files (*.sql)|*.sql|Text Files (*.txt)|*.txt"                         ;; the pattern to pass the filter box
;Pattern.i = 0                                                                 ;; the pattern selection is none

gFilename$ = OpenFileRequester(                                               ;; open
_           Title$, DefaultFile$, Pattern$, Pattern,                          ;; dialog
_           #PB_Requester_MultiSelection)                                     ;; box so we can request a file(s)

While gFilename$                                                              ;; if there is a gFilename$
  
  
  
  
  If ReadFile(0, gFilename$)                                                  ;; can we read it if so
    
    
    ;----------------------------------------------
    ; make sure a non zero length file exists
    ;----------------------------------------------
    gFileLength = Lof(0)                                                      ;; read length of file
    If gFileLength > 0                                                        ;; if length is zero run 'else' portion
      
      ;----------------------------------------------
      ; allocate memory
      ;----------------------------------------------
      ;*gFile = ReAllocateMemory(*gFile, gFileLength)                          ;; set/reset memory buffer
      *gFile = AllocateMemory(gFileLength)                                    ;; set/reset memory buffer
      
      
      checkLength = MemorySize(*gFile)                                        ;; get the length of memory buffer
      
      ;----------------------------------------------
      ; verify allocated memory length correct
      ;----------------------------------------------
      If checkLength = gFileLength                                            ;; verify memory allocated
        
        ;----------------------------------------------
        ; read file into memory
        ;----------------------------------------------
        checkLength = 0                                                       ;; reset
        checkLength = ReadData(0, *gFile, gFileLength)                        ;; put file in memory
        
        ;----------------------------------------------
        ; verify file in memory is correct length
        ;----------------------------------------------
        If checkLength = gFileLength                                          ;; verify read properly
          
          
          ;----------------------------------------------
          ; count amount to add to file
          ;----------------------------------------------
          lengthToAdd = CountTicks(*gFile)                                    ;; length to add to buffer
          
          ;----------------------------------------------
          ; create a new length variable
          ;----------------------------------------------
          newLength = gFileLength + lengthToAdd                               ;; calculate new file length
          
          ;----------------------------------------------
          ; set up the new
          ; length of the main file
          ;----------------------------------------------
          Delay(200)
          *gFile = ReAllocateMemory(*gFile, newLength)                        ;; change length of *buffer
          Delay(200)
          
          ;----------------------------------------------
          ; finally set up pointers
          ;----------------------------------------------
          *leftPointer = *gFile + gFileLength                                 ;; points to the end of original file
          *rightPointer = *gFile + newLength                                  ;; points to the end of the entire file
          Delay(200)
          
          Debug(Str(MemorySize(*gFile)) + " " + Str(*leftPointer) + " " + Str(*rightPointer))
          
          
          ; --------------------------------------------
          ;  if using assembler the
          ;  available registers are: eax, edx and ecx
          ; --------------------------------------------
          
          ticksToGo = lengthToAdd
          
          
          ;DEC *leftPointer                                       ;; start on the correct character
          *leftPointer = *leftPointer - 1
          
          While ticksToGo > 0                                     ;; have more to do
            ;Debug(*leftPointer)
            
            leftByte = PeekB(*leftPointer)
            rightByte = PeekB(*rightPointer)
            
            If leftByte = 39                                      ;; if its a tick mark
              *rightPointer = *rightPointer - 1                   ;; move right side pointer left
              PokeB(*rightPointer,leftByte)                       ;; write the tick mark
              *rightPointer = *rightPointer - 1                   ;; move right side pointer left
              PokeB(*rightPointer,leftByte)                       ;; write the tick mark again
              ticksToGo = ticksToGo - 1                           ;; loop control
            Else                                                  ;; otherwise
              *rightPointer = *rightPointer - 1                   ;; move right side pointer left
              PokeB(*rightPointer,leftByte)                       ;; write the byte
            EndIf                                                 ;; end if its a tick
            
            *leftPointer = *leftPointer - 1                       ;; get ready to get next character
            
          Wend
          
          *leftPointer = 0
          *rightPointer = 0
          
        EndIf                                                                       ;;
        
        
        ;;;;;;;;;
        
      Else
        MessageRequester ("File Load Error", "Not able to read file into memory: " + gFilename$,#PB_MessageRequester_Ok)
      EndIf                                                       ;; endif read file
      
    Else
      MessageRequester ("Insufficient Memory", "Insufficient memory for file: " + gFilename$,#PB_MessageRequester_Ok)
    EndIf                                                         ;; check memory was allocated
    
  Else
    ;; write the file name only on the card
    
  EndIf                                                           ;; if gFileLength > 0
  
  
  Debug(gFilename$ + " " + Str(MemorySize(*gFile)))
  
  FreeMemory(*gFile)
  gFilename$ = NextSelectedFileName()                             ;; goto next select file
  
Wend                                                            ;; end if gFilename$




rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: Memory Allocate Crash?

Post by rsts »

Ran successfully on dozens of text files + jpg's and a 700MB avi.

Possibly something else in the program, or is this it?

cheers
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Re: Memory Allocate Crash?

Post by Derek »

Code: Select all

Procedure.i CountTicks(*StringBuffer)                                           ;; count the ticks
  tickCount = 0                                                                 ;; init tick count
  fileLength = MemorySize(*StringBuffer)                                        ;; get the file length
  For c = 1 To fileLength                                                       ;; iterate through the file

*** this ^^^ should be 0 to filelength-1 ***

    *thisChar = *StringBuffer + c                                               ;; look at each character
    If PeekB(*thisChar) = 39                                                    ;; if its a tickmark
      tickCount = tickCount + 1                                                 ;; count it
    EndIf                                                                       ;; end if its a tickmark
  Next                                                                          ;; next character
  ProcedureReturn (tickCount)                                                   ;; done retun the count
EndProcedure
Not sure if it'll help but I would think the count loop is slightly wrong. In the original it misses the first character in memory which could be a tick and also peekb's a byte past the end of the buffer which may or may not cause problems.
benco5000
User
User
Posts: 13
Joined: Mon Mar 01, 2010 8:56 pm

Re: Memory Allocate Crash?

Post by benco5000 »

Thanks for such a quick response. I was beginning to think that it was a memory stick error. Turns out Derek was right.... although I still fail to see why that routine affects the other since it only returns a count. If I correct the counter in the CountTicks routine, it works. If I skew it slightly as it is shown then the program randomly fails in the While gFilename$ section. Thanks again!!
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Memory Allocate Crash?

Post by IdeasVacuum »

Derek is right, the procedure CountTicks will miss a tick if it is the first char in the file.

Tested with PB4.40 x86, WinXP32 SP3, no crashing:
  • Tick Count93
    8407 32521994 32522087
    C:\PROJECTS_DrvC\TickTest\TickTest01.txt 8407
    Tick Count110
    8444 32522014 32522124
    C:\PROJECTS_DrvC\TickTest\TickTest02.txt 8444
    Tick Count185
    8591 32522086 32522271
    C:\PROJECTS_DrvC\TickTest\TickTest03.txt 8591
    Tick Count139
    8502 32522043 32522182
    C:\PROJECTS_DrvC\TickTest\TickTest04.txt 8502
    Tick Count166
    8556 32522070 32522236
    C:\PROJECTS_DrvC\TickTest\TickTest05.txt 8556
    Tick Count215
    8651 32522116 32522331
    C:\PROJECTS_DrvC\TickTest\TickTest06.txt 8651
    Tick Count194
    8612 32522098 32522292
    C:\PROJECTS_DrvC\TickTest\TickTest07.txt 8612
    Tick Count235
    8691 32522136 32522371
    C:\PROJECTS_DrvC\TickTest\TickTest08.txt 8691
    Tick Count205
    8634 32522109 32522314
    C:\PROJECTS_DrvC\TickTest\TickTest09.txt 8634
    Tick Count236
    8705 32522149 32522385
    C:\PROJECTS_DrvC\TickTest\TickTest10.txt 8705
    Tick Count93
    8407 32521994 32522087
    C:\PROJECTS_DrvC\TickTest\TickTest11.txt 8407
    Tick Count110
    8444 32522014 32522124
    C:\PROJECTS_DrvC\TickTest\TickTest12.txt 8444
    Tick Count185
    8591 32522086 32522271
    C:\PROJECTS_DrvC\TickTest\TickTest13.txt 8591
    Tick Count139
    8502 32522043 32522182
    C:\PROJECTS_DrvC\TickTest\TickTest14.txt 8502
    Tick Count166
    8556 32522070 32522236
    C:\PROJECTS_DrvC\TickTest\TickTest15.txt 8556
    Tick Count215
    8651 32522116 32522331
    C:\PROJECTS_DrvC\TickTest\TickTest16.txt 8651
    Tick Count194
    8612 32522098 32522292
    C:\PROJECTS_DrvC\TickTest\TickTest17.txt 8612
    Tick Count235
    8691 32522136 32522371
    C:\PROJECTS_DrvC\TickTest\TickTest18.txt 8691
    Tick Count205
    8634 32522109 32522314
    C:\PROJECTS_DrvC\TickTest\TickTest19.txt 8634
    Tick Count235
    8702 32522147 32522382
    C:\PROJECTS_DrvC\TickTest\TickTest20.txt 8702
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Re: Memory Allocate Crash?

Post by Derek »

It could be that a tick is occupying that extra byte in memory so it gets counted and causes the subsequent loops to go wrong because they are geared up for more ticks in a file than there actually is. Anyway, glad to have helped.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Memory Allocate Crash?

Post by IdeasVacuum »

Well, PeekB(*thisChar) will potentially be 1 char outside of the file, so lengthToAdd could then be wrong, so then the memory allocation for the new length of file could be wrong? That's possibly something to do with it. (All credit to Derek for spotting this).
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: Memory Allocate Crash?

Post by freak »

These kinds of errors are always caused by such off-by-one memory overwrites. If you write more past a buffer, you will get a crash right away.

The Purifier in PB 4.50 is the tool to find them. It would have spottet this right away.
There is also this: http://www.purebasic.fr/blog/?p=55
quidquid Latine dictum sit altum videtur
Post Reply