Announcement

Collapse
No announcement yet.

Problem with Pointer to UDT

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

  • Problem with Pointer to UDT

    Hello Folks,

    I'm having trouble using a pointer to a UDT. The UDT is defined in an *.inc file and so is the pointer declaration, as per:

    Code:
      
    
    GLOBAL gGdPtr           AS GridDetails POINTER             ' Pointer to GridDetails

    Then in the main program I have:

    Code:
     
    '======================================================================================
      ' Start by allocating GridDetails memory.
      
      gGdPtr = Malloc( SIZEOF( GridDetails ) )                 ' Allocate GridDetails memory
    
      IF ISFALSE gGdPtr THEN EXIT FUNCTION                     ' No memory, bail
    
    
      '======================================================================================
      ' We now need separate memory blocks for the following arrays: string Data;
      ' Cell Attributes; Colunm Details; and Row Details.
    
      @gGdPtr.DataPtr     = Malloc( 4 )                        ' Memory for one pointer
      @gGdPtr.CellPtr     = Malloc( SIZEOF( CellAttributes ) * 1 )' Cell attributes
      @gGdPtr.ColPtr      = Malloc( SIZEOF( ColDetails ) * 1 ) ' Column Details
      @gGdPtr.RowPtr      = Malloc( SIZEOF( RowDetails ) * 1 ) ' Row Details
    The code doesn't appear to be working. All the UDT elements hold the same value as gGdPtr. IOW, the values @gGdPtr.DataPtr and @gGdPtr.CellPtr and @gGdPtr.ColPtr and @gGdPtr.RowPtr and gGdPtr are equal, as is every other element.

    What am I doing wrong?


    Pat

  • #2
    [deleted]
    Last edited by Eddy Van Esch; 21 Apr 2008, 07:38 AM.
    Eddy

    Comment


    • #3
      Hello Eddy,

      Thanks for your response. However, I'm not using a "@" when setting aside memory for gGdPtr, as in:

      Code:
       gGdPtr = Malloc( SIZEOF( GridDetails ) )                 ' Allocate GridDetails
      The other code allocates memory for later use and the memory pointers are stored in the UDT, so wouldn't I use the "@" in these instances?

      Pat

      Comment


      • #4
        We need to see more code. Draw up a compilable example and someone may be able to help...
        kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

        Comment


        • #5
          In the docs there's a note:
          If you declare a member of a structure as a pointer, the @ prefix is used with the member name, not the structure name.
          Might this be the problem? For example,
          Code:
            [email protected]     = Malloc( 4 )                        ' Memory for one pointer
            [email protected]     = Malloc( SIZEOF( CellAttributes ) * 1 )' Cell attributes
            [email protected]      = Malloc( SIZEOF( ColDetails ) * 1 ) ' Column Details
            [email protected]      = Malloc( SIZEOF( RowDetails ) * 1 ) ' Row Details

          Comment


          • #6
            Kev,

            The following code illustrates simply what I'm trying to do:

            Code:
            ' In an include file:
            
            TYPE Dummy
              Value1 AS LONG
              Value2 AS LONG
              Value3 AS LONG
            END TYPE
            
            GLOBAL Dumb AS dummy
            
            GLOBAL gDummyPtr  AS dummy POINTER
            
            
            ' In main code:
            
            gDummyPtr = Malloc( SIZEOF( dummy ) )
                                  
            @gDummyPtr.Value1 = 10
            @gDummyPtr.Value2 = 20
            @gDummyPtr.Value3 = 30
            What I find happening is that @gDummyPtr.Value1 = @gDummyPtr.Value2 = @gDummyPtr.Value1 = gDummyPtr.


            Pat

            Comment


            • #7
              Looks fine to me, although from your description it sounds as if "Dummy" is declared as a UNION. What about Malloc(), are you sure that's working correctly? What about "Dumb As Dummy", what is that used for?

              I use pointers and dynamic allocation (ie. GlobalAlloc) constantly without any trouble, so I doubt it's a compiler problem.
              kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

              Comment


              • #8
                >gDummyPtr = Malloc( SIZEOF( dummy ) )

                Compiler version?

                SIZEOF(UDTName) was not supported until... 7x? Prior to that SIZEOF( ) required a VARIABLE as an argument. (In this case it could be gDummyPtr = malloc (SIZEOF(@gDummyPtr))

                Also you might want to show us your malloc function.

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

                Comment


                • #9
                  Michael,


                  Compiler version?
                  Yes the PB version is 8.04.

                  The malloc function is something which I stole from you, as in:

                  Code:
                  FUNCTION Malloc( lBytes AS LONG ) AS LONG
                    '**************************************************************************************
                    ' Purpose:    This function allocates lBytes from the Heap using HeapAlloc() with the *
                    '             flags %HEAP_ZERO_MEMORY and %HEAP_NO_SERIALIZE. It assumes ghHeap is a  *
                    '             valid handle from a call to HeapCreate().                               *
                    '                                                                                     *
                    ' Parameter:  lBytes - The number of bytes to allocate.                               *
                    '                                                                                     *
                    ' Returns:    Pointer to allocated memory or Null on failure.                         *
                    '                                                                                     *
                    '**************************************************************************************
                  
                    IF ISFALSE ghHeap THEN                                   ' Check we have Heap pointer
                  
                      FUNCTION = 0
                      EXIT FUNCTION
                  
                    END IF
                  
                    FUNCTION = HeapAlloc( ghHeap, _
                                         %HEAP_ZERO_MEMORY OR %HEAP_NO_SERIALIZE, _
                                         lBytes )
                  
                  END FUNCTION

                  Kev,

                  the code:

                  Code:
                  GLOBAL Dumb AS dummy

                  has no purpose. A bad habit I picked, but I commented it out without seeing any change.

                  I agree that it's not likely to be a compiler problem, but I can't see what I've done wrong. I've used pointers to UDT's in PowerBASIC before without problems.


                  Pat

                  Comment


                  • #10
                    >IF ISFALSE ghHeap THEN

                    Where is your heap handle obtained?

                    Looks to me like malloc should be failing. Unless you are not showing us the code where you call HeapCreate.

                    BTW, my code was updated to include the 'private heap' versions of same.
                    http://www.powerbasic.com/support/pb...ad.php?t=24212
                    (Look ma no globals.)

                    One more possibility... malloc and subsequent assignments are working perfectly but the code you are using to test the results (not shown) is in error.

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

                    Comment


                    • #11
                      <deleted>
                      Last edited by Kev Peel; 21 Apr 2008, 08:55 AM. Reason: wrong info
                      kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

                      Comment


                      • #12
                        Pat,

                        This displays 10, 20, 30 on my pc.
                        Does it not on yours ?


                        Code:
                        #COMPILE EXE
                        #DIM ALL
                        
                        TYPE Dummy
                          Value1 AS LONG
                          Value2 AS LONG
                          Value3 AS LONG
                        END TYPE
                        
                        GLOBAL Dumb AS dummy
                        GLOBAL gDummyPtr  AS dummy POINTER
                        
                        #IF NOT %DEF(%WINAPI)
                          DECLARE FUNCTION GETPROCESSHEAP LIB "KERNEL32.DLL" ALIAS "GetProcessHeap" () AS LONG
                          DECLARE FUNCTION HEAPALLOC LIB "KERNEL32.DLL" ALIAS "HeapAlloc" (BYVAL hHeap AS DWORD, BYVAL dwFlags AS DWORD, BYVAL dwBytes AS DWORD) AS DWORD
                          DECLARE FUNCTION HEAPFREE LIB "KERNEL32.DLL" ALIAS "HeapFree" (BYVAL hHeap AS DWORD, BYVAL dwFlags AS DWORD, BYVAL lpMem AS DWORD) AS LONG
                          DECLARE FUNCTION HEAPREALLOC LIB "KERNEL32.DLL" ALIAS "HeapReAlloc" (BYVAL hHeap AS DWORD, BYVAL dwFlags AS DWORD, BYVAL lpMem AS DWORD, BYVAL dwBytes AS DWORD) AS DWORD
                          %HEAP_NO_SERIALIZE             = &H00000001
                          %HEAP_GENERATE_EXCEPTIONS      = &H00000004
                          %HEAP_ZERO_MEMORY              = &H00000008
                        #ENDIF
                        
                        #IF NOT %DEF(%HEAP_ALLOC_FLAGS)
                        ' See MSDN for options for flags.
                        %HEAP_ALLOC_FLAGS    = %HEAP_ZERO_MEMORY OR %HEAP_GENERATE_EXCEPTIONS
                        %HEAP_FREE_FLAGS     = 0&
                        #ENDIF
                        
                        FUNCTION malloc  (BYVAL NumberOfBytes AS LONG) AS DWORD
                          ' returns: address of block of size NumberOfBytes
                           FUNCTION = HEAPALLOC (GETPROCESSHEAP(), %HEAP_ALLOC_FLAGS, NumberOfBytes)
                        END FUNCTION
                        
                        
                        
                        FUNCTION PBMAIN
                        
                            gDummyPtr = Malloc( SIZEOF( dummy ) )
                            'gDummyPtr = VARPTR(Dumb)
                                                  
                            @gDummyPtr.Value1 = 10
                            @gDummyPtr.Value2 = 20
                            @gDummyPtr.Value3 = 30
                        
                            msgbox STR$(@gDummyPtr.Value1)
                            msgbox STR$(@gDummyPtr.Value2)
                            MSGBOX STR$(@gDummyPtr.Value3)
                            
                        END FUNCTION
                        Kind regards
                        Eddy

                        Comment


                        • #13
                          Michael,

                          ghHeap is set elsewhere. The comments for Malloc() says that it expects ghHeap to be a valid handle.

                          There's no test code, per se, although I've placed various bits of code trying to figure the problem out. I've been using PB's debug feature to test values - these's no problem with that is there?

                          Malloc appears to be returning correct values. BUT, the assigning to the UDT members doesn't make sensse.

                          For example, using the code I originally provided, all the UDT members have the same value, being the value of the UDT pointer "gGdPtr". Even if I comment out all the other allocations, the values are still there.


                          Eddy,

                          I haven't tried the dummy code out. I put that together just to show in a simple way what I was trying to do. If you like I can send you the real code to look at - to your private email address.

                          The more I look at it the more I think I've made a simple mistake here BUT for the life of me, I just can't see it.


                          Pat

                          Comment


                          • #14
                            Pat,

                            Can you show us your 'GridDetails' definition ?

                            Kind regards
                            Eddy

                            Comment


                            • #15
                              Eddy,

                              Here's the defintion:

                              Code:
                              TYPE GridDetails
                                hGridWnd              AS DWORD                           ' Grid handle for this data
                                DataPtr               AS LONG                            ' Cell text data base pointer
                                CellPtr               AS LONG                            ' Absolute ptr to CellDetails
                                ColPtr                AS LONG                            ' Absolute ptr to ColDetails
                                RowPtr                AS LONG                            ' Absolute ptr to RowDetails
                              
                                Cols                  AS BIT * 30 IN DWORD               ' Column count
                                FixedCol              AS BIT * 2                         ' %NO_FIXED_COL, %FIXED_COL or
                                                                                         '                %OUTLINE_COL
                                ColWidth              AS BIT * 31 IN DWORD               ' Default Column width
                                AdjustCol             AS BIT * 1                         ' %NO_ADJUST_WIDTH or
                                                                                         '          %ALLOW_ADJUST_WIDTH
                              
                                Rows                  AS BIT * 31 IN DWORD               ' Row Count
                                FixedRow              AS BIT * 1                         ' %NO_FIXED_ROW OR %FIXED_ROW
                                                                                           '
                                RowHeight             AS BIT * 31 IN DWORD               ' Row height in pixels
                                AdjustRow             AS BIT * 1                         ' %NO_ADJUST_HEIGHT or
                                                                                         '         %ALLOW_ADJUST_HEIGHT
                                hFont                 AS DWORD                           ' Default is SYSTEM_FONT
                                BackColour            AS LONG                            ' Default to %COLOR_WINDOW
                                ForeColour            AS LONG                            ' Default to %COLOR_WINDOWTEXT
                                DefaultFont           AS DWORD                           ' Default font for cell data
                                Alignment             AS BIT * 31 IN DWORD               ' %TEXT_LEFT_ALIGN or
                                                                                         '         %TEXT_RIGHT_ALIGN or
                                                                                         '           %TEXT_CENTRE_ALIGN
                                DataType              AS BIT * 1                         ' %TEXT_DATA_TYPE
                              
                                Row                   AS BIT * 30 IN DWORD               ' Selected Row
                                GridCursor            AS BIT * 2                         ' %CURSOR_CELL, %CURSOR_ROW or
                                                                                         '                 %CURSOR_NONE
                                Col                   AS BIT * 31 IN DWORD               ' Selected Column
                                GridLines             AS BIT * 1                         ' %SHOW_GRID_LINES OR
                              END TYPE                                                   '               %NO_GRID_LINES
                              
                              GLOBAL gGd AS GridDetails                                  ' LEN(GridDetails) = 64
                              
                              
                              
                              '****************************************************************************************
                              ' Global Variables
                              
                              GLOBAL gGdPtr           AS GridDetails POINTER             ' Pointer to GridDetails
                              I think I've already provided any other salient code bits.


                              Pat

                              Comment


                              • #16
                                Hello All,

                                Oh dear, it appears that PB's "Variable Watcher" used when debugging doesn't give a valid answer when dealing with pointers to UDT's. When I assigned the UDT values to local variables, I got the correct results.

                                So, for me, it's back to the drawing board. I have "Memory Access Violation" error somewhere else.

                                Sorry about all this


                                Pat

                                Comment


                                • #17
                                  it appears that PB's "Variable Watcher" used when debugging doesn't give a valid answer when dealing with pointers to UDT's.
                                  If that's the case and it is not suposed to be, send in your code to PB as a bug report so it gets fixed and others won't have to go through it.

                                  That's only fair, as others have invested their time in the problem, too, and a little return on investment is in order.

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

                                  Comment


                                  • #18
                                    IIRC, I don't think the debugger supports indirection for the watch window. It will display the pointer address, not the data value. Someone correct me if I'm wrong.
                                    kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

                                    Comment


                                    • #19
                                      Michael,

                                      Yes, I've sent a report in to Support.


                                      Kev,

                                      I'm not aware of any limitations of the watch window. If there is, I'm sure PB will let me know.

                                      Thanks for your assistance.


                                      Pat

                                      Comment


                                      • #20
                                        Originally posted by Kev Peel View Post
                                        Someone correct me if I'm wrong.
                                        Kev, you're wrong!

                                        Code:
                                        TYPE tMyUDT
                                            s AS STRING * 20
                                            l AS LONG
                                        END TYPE
                                        
                                        GLOBAL myudt AS tmyudt
                                        '--------------------------------------
                                        CALLBACK FUNCTION ShowDIALOG1Proc()
                                            LOCAL p AS tMyUDT PTR
                                            
                                            SELECT CASE AS LONG CBMSG
                                                CASE %WM_INITDIALOG
                                                    MyUDT.s = "hello"
                                                    MyUDT.l = 123
                                                    p = VARPTR(myudt)
                                        @p.l and @p.s both give the expected values in the watch window.

                                        Comment

                                        Working...
                                        X