Announcement

Collapse
No announcement yet.

Passing arrays from a SUB to MAIN

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

  • Passing arrays from a SUB to MAIN

    I am trying to pass an array that was created in a SUB
    to the calling MAIN program. However, the MAIN program
    does not know it's size since it's size is determined
    in the SUB. How can I pass it to the calling MAIN program
    without being forced to over-DIMension it then using
    REDIM PRESERVE to cut it to the right size? Is there another
    way of doing it or what I proposed is the only
    way?

    Thanks


    ------------------
    Regards
    Haitham
    Regards
    Haitham

  • #2
    Sub Test( byref a() as Long )

    Redim a( 0 to 1 )

    'again...
    'again..

    end sub


    Sub main()

    Dim a( 0 to 0 ) As Local long

    Test( a )

    end sub


    ------------------
    http://www.hellobasic.com
    Click here for PwrDev.

    [This message has been edited by Edwin Knoppert (edited July 11, 2007).]
    hellobasic

    Comment


    • #3
      Thanks Edwin for your propmpt reply.

      I tried the following, it prints the right results but it gives
      me a 'memory could not be read error' error.

      Any suggestions?

      Code:
      #COMPILE EXE
      #DIM ALL
      
      DECLARE SUB Sub2Main(A() AS LONG)
      
      FUNCTION PBMAIN () AS LONG
      
          DIM J AS LONG
          
          DIM B(1 TO 1) AS LONG
          
          Sub2Main B()
          
          FOR J = 1 TO 10
            PRINT B(J)
          NEXT J
          
          WAITKEY$
      
      END FUNCTION
      
      SUB Sub2Main(A() AS LONG)
        
        'Do some calculations which will detrmine the size of A
        'then size A accordingly then pass it to PBMAIN
        
        LOCAL I AS LONG
        I = 10
        DIM A(1 TO I)
        
        FOR I = 1 TO 10
          A(I) = I*I
        NEXT I
        
      END SUB
      Thanks,



      ------------------
      Regards
      Haitham
      Regards
      Haitham

      Comment


      • #4
        Code:
        ReDim A(1 To I)
        ------------------
        Regards,
        Peter
        Regards,
        Peter

        Comment


        • #5
          Try REDIM instead of DIM in SUb2Main.

          IF that doesn't do it then DIM or REDIM B(0)* before passing to sub2main (where you REDIM). I do this a lot.

          Just to answer the question... LBOUND/UBOUND can be used to get the number of elements in the array on return

          *I seem to recall, you can't REDIM a zero-based array to make it a 1-based array, so you may have to DIM/REDIM B(1) in main before passing.

          ** note that with PB < 8.01, you can get memory leeks when REDIM'ing a passed array. In PBmain it makes no difference, but if done from procedures, use ERASE in same procedure when done with array.




          Comment


          • #6
            Peter, Michael

            Many thanks for your response. I used REDIM in the Sub2Main
            subroutine and it worked fine.

            I am trying to understand the logic of what has been done.
            Firstly B was dimensioned as a single element array. Then
            subroutine Sub2Main was called which returned the 10 element
            array A as the array B. So it seems that PB dynamically
            resized B to size 10. Is that right?

            Thanks,




            ------------------
            Regards
            Haitham
            Regards
            Haitham

            Comment


            • #7
              Code:
              #COMPILE EXE
              #DIM ALL
              DECLARE SUB Sub2Main(A() AS LONG)
              
              FUNCTION PBMAIN () AS LONG
                  DIM J AS LONG
                  REDIM B(0) AS LONG                    'DIM or REDIM
                  Sub2Main B()
                  ? "Returned upper bound "UBOUND(b)    'returns 0 if DIM in Sub2Main
                  FOR J = 1 TO 10
                    PRINT B(J)
                  NEXT J
                  WAITKEY$
              END FUNCTION
              
              SUB Sub2Main(A() AS LONG)
                LOCAL I AS LONG
                I = 10
                'DIM A(1 TO I)                           'error, REDIM required
                REDIM A(1 TO I)                          'correct, REDIM required
                
                ? "Upper bound in Sub2Main"UBOUND(a)
                FOR I = 1 TO 10
                  A(I) = I*I
                NEXT I
              
              END SUB
              ------------------

              Comment


              • #8
                ...Where was my local for?



                ------------------
                http://www.hellobasic.com
                Click here for PwrDev.
                hellobasic

                Comment


                • #9
                  I think the "AS LONG" in sub2main may have confused the compiler into thinking you wanted a new array and did not mean the same array as was passed, so it did that.

                  FWIW, I no longer use DIM for arrays at all, I always use REDIM. Never had a problem.

                  Comment


                  • #10
                    Creating or modifying an array in a sub, then using it elsewhere
                    is not really a problem if you are aware of the matter of scope.
                    Scope defines in what context a variable or array is recognized.
                    If it's GLOBAL, then the same variable or array is recognized at
                    all levels. If it is LOCAL or STATIC, then it is only known at
                    the current level. The difference between LOCAL and STATIC is that
                    LOCAL variables and arrays are always reinitialized each time you
                    enter the current level; whereas STATIC variables and arrays are
                    retained and can be reaccessed the next time you enter the current
                    level. And by "current level", we mean the current SUB or FUNCTION.

                    If you define a variable or array as LOCAL in a SUB or FUNCTION, then
                    it essentially confined to the scope of that SUB or FUNCTION. When
                    you exit, it is as though it does not exist. In fact it might, as
                    nothing has yet eliminated or altered it. But the content of strings
                    actually reside on the heap, and the mechanism for freeing up that
                    memory has been signalled that these are now scrap, so they are
                    at risk of being reassigned.

                    But creating arrays inside a SUB or FUNCTION to export out to the
                    MAIN body is sort of awkward. First, if you define them as GLOBAL,
                    no export is necessary, they are just there. Since the SUB or
                    FUNCTION is only able to create that one array, it isn't like
                    creating any number of arrays and having a sub that can work on
                    any of them by reference. You loose the flexibility that the
                    SUB or FUNCTION can provide.

                    The second approach would be to define the array in the outside
                    process, then pass a reference to it when you call the SUB or
                    FUNCTION, which can then act on it as you desire, and on exit,
                    the changes will have been implemented.

                    You have to ask yourself why you need to do something that involves
                    an array, then whether a SUB or FUNCTION would be the best place
                    to do it or not. You already have one FUNCTION in place, which
                    is your PBAIN() or WINMAIN() function. Things that you only
                    intend to do one time in the course of running your program do
                    not generally require a separate SUB or FUNCTION of their own.
                    However, some people see their purpose as a series of discrete
                    steps, and it helps them to write code specific to each step,
                    and for this they write SUBS or FUNCTIONS in which they place
                    those steps. There is absolutely nothing wrong with doing it this
                    way. It can also help make programs easier to maintain, because
                    it organizes your activity. But it is not strictly necessary,
                    and does cause some additional overhead when the program is
                    being executed.



                    ------------------
                    Old Navy Chief, Systems Engineer, Systems Analyst, now semi-retired

                    Comment


                    • #11
                      Many thanks Donald for your analysis.

                      I agree with all you've said.
                      The reason I need to pass an array sized in a subroutine back
                      to the calling program is that I am developing a program and
                      I want to test each part of it before intergrating the parts
                      into a single program and so far I've done most of the bits
                      and pieces and tested them and they are working as intended
                      and all I need to do now is integrate them in the shape of
                      subroutines and the bigger program is done.

                      Cheers,

                      ------------------
                      Regards
                      Haitham
                      Regards
                      Haitham

                      Comment

                      Working...
                      X