Announcement

Collapse
No announcement yet.

arrays of fixedlen strings

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • arrays of fixedlen strings

    I would have liked to do
    DIM lines_of_text(139) as string * 50
    and then fill the array with strings varying in length from 3 to 50.
    I imagined this would allocate memory for the array only once.

    However, I am only allowed to do
    DIM lines_of_text(139) as string

    Question 1 Will this cause lots of memory reallocation every time I insert a line ?

    Question2 If so, can anyone think of a way to avoid all that memory reallocation ?

  • #2
    What compiler are you using? On My System,
    Dimensioning "DIM lines_of_text(139) AS STRING * 50" IS possible.
    and this example below takes around 0.3 seconds.

    139 lines of 50 characters each is nothing. I dont think it will cause
    lots of memory reallocation when you insert a new line.

    Code:
    #COMPILE EXE
    #DIM ALL
    
    FUNCTION PBMAIN () AS LONG
        
    LOCAL Index AS LONG
    LOCAL T AS SINGLE
    DIM lines_of_text(139) AS STRING * 50
    
    T = TIMER
    
    FOR Index = 1 TO 139
     lines_of_text(Index) = "Example text: This is an example of a string." & FORMAT$(Index)
    NEXT Index
    
    FOR Index = 1 TO 5000
     REDIM PRESERVE lines_of_text(UBOUND(lines_of_text())+1)
     ARRAY INSERT lines_of_text(50), "Example text: This is an example of a string." & FORMAT$(Index)
    NEXT Index
    
    MSGBOX "All the process took: " & STR$(TIMER-T),,"Task Complete"
        
    
    END FUNCTION
    I

    Comment


    • #3
      Doing it this way takes 0.00 seconds on my system.

      Code:
      #COMPILE EXE
      #DIM ALL
      
      FUNCTION PBMAIN () AS LONG
          
      LOCAL Index AS LONG
      LOCAL T AS SINGLE
      DIM lines_of_text(139) AS STRING * 50
      
      T = TIMER
      
      FOR Index = 1 TO 139
       lines_of_text(Index) = "Example text: This is an example of a string." & FORMAT$(Index)
      NEXT Index
      
      REDIM PRESERVE lines_of_text(UBOUND(lines_of_text())+5000)
      
      FOR Index = 140 TO 5139
       lines_of_text(Index) = "Example text: This is an example of a string." & FORMAT$(Index)
      NEXT Index
      
      MSGBOX "All the process took: " & STR$(TIMER-T),,"Task Complete"
          
      
      END FUNCTION
      Last edited by Elias Montoya; 20 Mar 2008, 04:56 PM.

      Comment


      • #4
        My compiler is PBWin 8.04
        My reasons for saying that
        dim myarray(139) as string * 50 was not allowed
        were
        1) that my compiler would not accept * 50
        2) that I could find no such example in PBHelp

        Thank you, both, for pointing out that it is possible to do what I want.
        Clearly something else must be wrong with my code.
        I shall now go and check everything again.

        Thanks for the help, and I'm sorry to have troubled you.
        With best regards, Ralph.

        Comment


        • #5
          What about ASCIIZ * 50
          ?

          Unless I mis-read the docs, String*50 and ASCIIZ*50 are the same thing? (not sure about nulls though)
          Engineer's Motto: If it aint broke take it apart and fix it

          "If at 1st you don't succeed... call it version 1.0"

          "Half of Programming is coding"....."The other 90% is DEBUGGING"

          "Document my code????" .... "WHYYY??? do you think they call it CODE? "

          Comment


          • #6
            Ralph,

            Try this:
            LOCAL Index AS LONG
            LOCAL T AS SINGLE
            LOCAL lines_of_text() AS STRING * 50
            DIM lines_of_text(139)

            Cliff,

            To have upto 50 characters in ASCIIZ would be:

            LOCAL MyStr AS ASCIIZ * 51

            because the last character is always NUL.

            Cheers,
            Dale

            Comment


            • #7
              The fixed STRING * [size] type auto-pads with spaces when you make an assignment, whereas the ASCIIZ type just NULL-terminates after the data. ASCIIZ is most compatible with the API, and the fixed STRING is backwards compatible with older code and for those situations where you might need the padding.

              1) that my compiler would not accept * 50
              All versions of PB/WIN should accept that syntax. Can you show us the failing code and compile error?
              kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

              Comment


              • #8
                You could always declare a string, use string$ to make it "of a length" and manage your own substring allocation within it, either using byte pointers or MID$. It would depend a bit on the context.

                Comment


                • #9
                  Another alternative is have an array of ASCIIZ PTRS and use

                  DIM MyszArray(10) AS ASCIIZ PTR

                  MyszArray(0) = SysAllocStringByteLen(szString,LEN(szString))

                  Dont forget to deallocate

                  SysFreeString MyszArray(0)

                  James

                  Comment


                  • #10
                    Originally posted by jcfuller View Post
                    MyszArray(0) = SysAllocStringByteLen(szString,LEN(szString))
                    like it!

                    Comment


                    • #11
                      Originally posted by Elias Montoya View Post
                      Doing it this way takes 0.00 seconds on my system.
                      Here's yet another fast way. The kewl timer is thanks to Dave Roberts!

                      Code:
                      #COMPILE EXE
                      #DIM ALL
                      
                      '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Dave Roberts' timer macros--best used in an include file so available any time.
                      DECLARE FUNCTION QueryPerformanceCounter LIB "KERNEL32.DLL" ALIAS "QueryPerformanceCounter" (lpPerformanceCount AS QUAD) AS LONG
                      DECLARE FUNCTION QueryPerformanceFrequency LIB "KERNEL32.DLL" ALIAS "QueryPerformanceFrequency" (lpFrequency AS QUAD) AS LONG
                      
                      MACRO onTimer
                        LOCAL qFreq, qOverhead, qStart, qStop AS QUAD
                        LOCAL f AS STRING
                        f = "#.###"
                        QueryPerformanceFrequency qFreq
                        QueryPerformanceCounter qStart ' Intel suggestion. First use may be suspect
                        QueryPerformanceCounter qStart ' So, wack it twice <smile>
                        QueryPerformanceCounter qStop
                        qOverhead = qStop - qStart     ' Relatively small
                      END MACRO
                      
                      MACRO goTimer = QueryPerformanceCounter qStart
                      MACRO stopTimer = QueryPerformanceCounter qStop
                      
                      MACRO showTimer = USING$(f,(qStop - qStart - qOverhead)*1000000/qFreq /1000) + " milliseconds"
                      '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                      
                      FUNCTION PBMAIN () AS LONG
                      
                      LOCAL Index AS LONG
                      LOCAL T AS SINGLE
                      LOCAL preString AS STRING
                      onTimer      'ready timer for use
                      goTimer      'start timing
                      
                      DIM lines_of_text(5139) AS STRING * 50
                      FOR Index = 1 TO 139
                       lines_of_text(Index) = "Example text: This is an example of a string." & FORMAT$(Index)
                      NEXT Index
                      
                      REDIM PRESERVE lines_of_text(UBOUND(lines_of_text())+5000)
                      
                      FOR Index = 140 TO 5139
                       lines_of_text(Index) = "Example text: This is an example of a string." & FORMAT$(Index)
                      NEXT Index
                      
                      stopTimer
                      MSGBOX "Original process took: " & showTimer  'STR$(TIMER-T),,"Task Complete"
                      
                      goTimer
                      
                      preString = REPEAT$(5139, "Example text: This is an example of a string.     ")
                      REDIM lines_of_text(1 TO 5139) AS STRING * 50 AT STRPTR(preString)
                      
                      stopTimer
                      MSGBOX "Absolute array process took: " & showTimer                                    
                      
                      END FUNCTION

                      Comment


                      • #12
                        Originally posted by Chris Holbrook View Post
                        like it!
                        Yeah. I use it all the time primarily for strings in udts. No need to preallocate with ASCIIZ * xxx to make sure you have enough room for all eventual sizes.

                        If I'm not mistaken it's the same call PB uses for STRING allocation.

                        James

                        Comment


                        • #13
                          Another neat feature is you have the length available too.

                          James
                          Code:
                          #COMPILE EXE
                          #DIM ALL
                          #INCLUDE "WIN32API.INC"
                          FUNCTION PBMAIN () AS LONG
                          
                              LOCAL szPtr AS ASCIIZ PTR
                              LOCAL dwPtr AS DWORD PTR
                          
                              szPtr = SysAllocStringByteLen("James",LEN("James"))
                              dwPtr = szPtr
                              DECR dwPtr
                              PRINT @szPtr
                              PRINT "Len = ";FORMAT$(@dwPtr)
                              WAITKEY$
                              SysFreeString szPtr
                          
                          END FUNCTION

                          Comment


                          • #14
                            "Can you show us the failing code and compile error"

                            Problem was solved after Elias Montoya said it should work.
                            Code shown on this site:-
                            DIM lines_of_text(139) as string * 50
                            was a simplified version of my actual code.
                            The actual code was much more complicated and it had a syntax error.

                            Comment

                            Working...
                            X