Announcement

Collapse
No announcement yet.

GlobalAlloc...

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

  • GlobalAlloc...

    Hi all,

    If i allocate some memory:
    Code:
        dwData = GlobalAlloc(%LPTR, ah.iLen)
    and then use dwData in the following way:
    Code:
        dim temp(10,10) as long at dwData
    is it then ok NOT to use GlobalFree...I would expect PB to take
    over the memory management.

    Regards
    Peter


    ------------------
    [email protected]
    www.dreammodel.dk

  • #2
    No, DIM AT tells the PB compilers to use pre-allocated memory, and to not de-allocate the memory when the array is released.

    DIM AT is very "soft". For example, when you DIM an array AT a certain location, the array elements are not initialized to zero.

    Look at it this way... If you created a 10k memory block, and then used DIM AT to overlay just 5k of that, how could it release the memory? And since DIM AT has no way of knowing how large the allocated memory block is...

    -- Eric

    ------------------
    Perfect Sync: Perfect Sync Development Tools
    Email: mailto:[email protected][email protected]</A>

    "Not my circus, not my monkeys."

    Comment


    • #3
      Thanks...i see your point...

      ------------------
      [email protected]
      www.dreammodel.dk

      Comment


      • #4
        GlobalAlloc does not return an address to DIM .. AT. It returns a handle.

        You get the address by executing GlobalLock(handle).

        After you DIM .. AT address, you can use PB to manipulate the array elements.

        When you are done, you can use GlobalUnlock and GlobalFree to return the memory to the system pool.

        Note that you must leave the memory locked (well, under Win/32 you really don't but you should) if you want to use the array elements, otherwise PB will be trying to acces memory no longer owned by the application, which, of course, means a GPF.

        MCM


        Michael Mattias
        Tal Systems Inc. (retired)
        Racine WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Guys --
          What do you think about CoTaskMemAlloc/Free ?

          ------------------
          E-MAIL: [email protected]

          Comment


          • #6
            Originally posted by Michael Mattias:

            Note that you must leave the memory locked (well, under Win/32 you really don't but you should) if you want to use the array elements, otherwise PB will be trying to acces memory no longer owned by the application, which, of course, means a GPF.
            Why should i if i dont have to?

            Regards
            Peter

            ------------------


            [This message has been edited by Peter P Stephensen (edited October 02, 2000).]
            [email protected]
            www.dreammodel.dk

            Comment


            • #7
              Below is the code I use. Note that since I use the %GMEM_FIXED parameter is specified, the return value is the actual pointer to the memory not a handle.
              Best Regards,
              Don

              Code:
              '
              '  pb_mem.bas
              '
              '  Power Basic memory allocation routines.
              '  By Don Dickinson
              '  [email protected]
              '  Sept, 2000
              '
              '  Hereby public domain. Use as you see fit. 
              '
              #If Not %def(%PB_MEM_BAS)
              %PB_MEM_BAS = 1
              
              '- I assume that if %GMEM_FIXED isn't defined, then
              '  none of the windows api is included (win32api.inc)
              '  so I declare everything that's needed by this module.
              '
              #if not %def(%GMEM_FIXED)
                 %GMEM_FIXED                                  = &H0
                 %GMEM_MOVEABLE                               = &H2
                 %GMEM_NOCOMPACT                              = &H10
                 %GMEM_NODISCARD                              = &H20
                 %GMEM_ZEROINIT                               = &H40
                 %GMEM_MODIFY                                 = &H80
                 %GMEM_DISCARDABLE                            = &H100
                 %GMEM_NOT_BANKED                             = &H1000
                 %GMEM_SHARE                                  = &H2000
                 %GMEM_DDESHARE                               = &H2000
                 %GMEM_NOTIFY                                 = &H4000
                 %GMEM_LOWER                                  = %GMEM_NOT_BANKED
                 %GMEM_VALID_FLAGS                            = &H7F72
                 %GMEM_INVALID_HANDLE                         = &H8000
                 Declare Function GlobalAlloc Lib "KERNEL32.DLL" Alias "GlobalAlloc" _
                       ( ByVal wFlags As Long, ByVal dwBytes As Long) As Long
                 Declare Function GlobalFree Lib "KERNEL32.DLL" Alias "GlobalFree" _
                       ( ByVal hMem As Long) As Long
              
              #endif         
              
              '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              '  GetMem
              '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              Function GetMem(ByVal iBytes As Long) As Long
              
                 Function = GlobalAlloc(%GMEM_FIXED or %GMEM_ZEROINIT, iBytes)
              
              End Function
              
              
              '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              '  FreeMem
              '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              Sub FreeMem(ByVal ptrMem As Long)
                 If ptrMem Then
                    GlobalFree ptrMem
                 End If
              End Sub
              
              #endif

              [This message has been edited by Don Dickinson (edited October 02, 2000).]
              Don Dickinson
              www.greatwebdivide.com

              Comment


              • #8
                Correct me if I'm wrong but I believe GlobalAlloc is left over from 16bit.

                I personally use HeapAlloc.

                James


                ------------------


                [This message has been edited by jcfuller (edited October 02, 2000).]

                Comment


                • #9
                  jcfuller --

                  You are right...(and very clever)

                  Regards
                  Peter

                  ------------------
                  [email protected]
                  www.dreammodel.dk

                  Comment


                  • #10
                    I guess I should have read my MSDN and discovered that GlobalAlloc is quasi-obsolete now:

                    From MSDN Library:

                    The GlobalAlloc function allocates the specified number of bytes from the heap. Win32 memory management does not provide a separate local heap and global heap.

                    Note The global functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions. However, the global functions are still used with DDE and the clipboard functions.
                    ...
                    Return Values
                    If the function succeeds, the return value is a handle to the newly allocated memory object.
                    I think that "the handle=the address" is coincidence.

                    And yes, this is leftover from Win/16

                    MCM

                    Michael Mattias
                    Tal Systems Inc. (retired)
                    Racine WI USA
                    [email protected]
                    http://www.talsystems.com

                    Comment


                    • #11
                      I make use of heapalloc a while now.
                      Pretty easy.

                      Use "ByVal hMem", the hmem param is "AS ANY" !

                      I also exp. a problem while realloc > 200x a small amount of mem.
                      It crashes while i actually fill it (when > 200)
                      It looks an incorrect address, don't know yet.
                      I solved it by using a 'steady' mem but it's no solution.

                      Anyone?


                      ------------------
                      [email protected]
                      hellobasic

                      Comment


                      • #12
                        Originally posted by Semen Matusovski:
                        Guys --
                        What do you think about CoTaskMemAlloc/Free ?

                        Semen,
                        I don't have any literature ( or if I do, I can't find it ) on CoTaskMemAlloc /Free.
                        What is it primarily used for?
                        Advantages / Disadvanatges vs HeapAlloc?

                        James


                        ------------------

                        Comment


                        • #13
                          james --
                          this is a "wrapper" for imalloc interface.
                          advantage (for me) - very easy in use.
                          you can find a sample in http://www.powerbasic.com/support/pb...ad.php?t=14863

                          ------------------
                          e-mail: [email protected]

                          Comment


                          • #14
                            Semen,
                            I do have the ole2 help file so I know it's usage but not the details.

                            What happens if one forgets to call CoTaskMemFree?

                            With the heap functions the memory used is automatically freed when the application
                            terminates.

                            James



                            ------------------

                            Comment


                            • #15
                              James --
                              I tested under Win2000 only.
                              Yes, memory is automatic freed also.
                              Almost sure that it will be the same results in another OSes.




                              ------------------
                              E-MAIL: [email protected]

                              Comment


                              • #16
                                With GMEM_FIXED (or one of the flag sets that includes this bit),
                                GlobalAlloc returns a pointer, not a handle. 16-bit Windows
                                required handles because memory management had to be done in
                                software, so there had to be a mechanism for disassociating the
                                memory location with the handle. 32-bit Windows gets to use CPU
                                hardware features to remap a pointer to point to different
                                memory areas without needing to change the pointer itself, so
                                handles are no longer required.

                                I don't think this applies without the GMEM_FIXED qualifier, but
                                it's been quite a while since I've looked at it.

                                ------------------
                                Tom Hanlin
                                PowerBASIC Staff

                                Comment


                                • #17
                                  First I want to mention that I'm not arguing about Heap vs Ole, I'm trying to
                                  discover what are the advantages(if any) of using ole. I figure if
                                  Semen uses it it must have some merits that I'm missing .

                                  From the ole help file I see that the memory is not initialized where with
                                  HeapAlloc you can have it zeroed out. I prefer the block initialized.

                                  With HeapAlloc fragmentation is always a worry.
                                  Do the ole functions suffer from this?

                                  James

                                  ------------------


                                  [This message has been edited by jcfuller (edited October 03, 2000).]

                                  Comment


                                  • #18
                                    Hi James

                                    the CoTaskMem* functions are used by COM (IMalloc::Alloc) to
                                    allocate memory (but you knew that).

                                    Since COM objects can cross process boundaries and travel across
                                    the network as well as be used by different languages it was necessary
                                    to design a unified allocation scheme which is used by the underlying COM
                                    implementation.

                                    I may be wrong but I believe that the CoTaskMem* functions use the
                                    Heap functions to implement memory allocation so I would not expect
                                    them to be more efficient (the only sure way would be to benchmark).


                                    Cheers

                                    Florent

                                    ------------------

                                    Comment


                                    • #19
                                      James --

                                      I beleive that by design the central part of COM interface should be enough effective, not less than Heap (probably, they are based on the same code).
                                      And MSDN talks “The CoTaskMemAlloc function has the advantage of working well in either C, C++, or Visual Basic. It is also the only way to share memory in a COM-based application, since MIDL uses CoTaskMemAlloc and CoTaskMemFree to marshal memory”.

                                      Now main argument: I am too old and lazy to remember Heap functions with a lot of parameters .

                                      PS. Fragmentation - yes, exist (but virtual <> physical)
                                      Not initialized -- For me it's rather plus (anyway there is FillMemory)




                                      ------------------
                                      E-MAIL: [email protected]

                                      Comment


                                      • #20
                                        I made a little test. Results (under Win2000, P-III-550) fully satisfied me.
                                        80-150 ms (depends of chunks) to allocate/free 32 Mb.
                                        Code:
                                            #Compile Exe
                                            #Register None
                                            #Dim All
                                            #Include "win32api.inc"
                                            Declare Function CoTaskMemAlloc Lib "ole32.dll" Alias "CoTaskMemAlloc" (ByVal Dword) As Dword
                                            Declare Sub CoTaskMemFree Lib "ole32.dll" Alias "CoTaskMemFree" (ByVal Dword Ptr)
                                            Function PbMain
                                               Local i1 As Long, i2 As Long, s As Long, n As Long, sPtr As Dword, t1 As Single, t2 As Single, w As String
                                               s = 1
                                               t1 = GetTickCount
                                               %nn = 16 ' (* 2) Mb
                                               For i1 = 1 To 7
                                                  n = %nn * 1024& / s ' 32 ( * 2) Mb
                                                  ReDim aPtr(1 To n) As Dword
                                                  For i2 = 1 To n
                                                     ' Two steps forward, one behind
                                                     sPtr = CoTaskMemAlloc(1024& * s)
                                                     aPtr(i2) = CoTaskMemAlloc(1024& * s)
                                                     CoTaskMemFree sPtr
                                                  Next
                                                  For i2 = 1 To n
                                                     CoTaskMemFree aPtr(i2)
                                                  Next
                                                  t2 = GetTickCount
                                                  w$ = w$ + $CRLF + "Size =" + Str$(s) + " Kb: " + _
                                                     Format$(1000# * (t2 - t1) / (2# * n), "#.######") + _
                                                     " ms per 1000 CoTaskMemAlloc/Free; total " + Format$(t2 - t1, "# ms")
                                                  t1 = t2: s = s * 2
                                                Next
                                                MsgBox w$, ,  "Allocate/Free" + Str$(%nn) + " Mb (twice)"
                                            End Function
                                        Florent, what about Heap ?

                                        PS. As I understand, allocated memory is thread-safety automatic.
                                        Or I'm wrong ?

                                        ------------------
                                        E-MAIL: [email protected]

                                        Comment

                                        Working...
                                        X