Results 1 to 20 of 20

Thread: [Not really Resolved] - Seasoned Programmer -- Simple Problem

  1. #1

    Thread Starter
    Fanatic Member HaxSoft's Avatar
    Join Date
    May 2000
    Location
    Ohio
    Posts
    593

    Unhappy [Not really Resolved] - Seasoned Programmer -- Simple Problem

    Maybe I am dummy, BUT:

    if I have a function such as

    Code:
    void my_func(char *x, long xlen){
    /*
        something here
    */
    }
    How do I verify that the *x does NOT point to something that is shorter than xlen bytes?

    I tried searching this forum, but can't seem to find the answer.

    CAN I at all verify this???
    Last edited by HaxSoft; Sep 27th, 2002 at 11:36 AM.

  2. #2
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Not portably. In fact, it's very difficult to check that it's even a real pointer.

    Basically, check for NULL. If it's not, assume it's a real pointer of the correct length.

    Any problems caused are the fault, and responsibility of, the calling function.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  3. #3
    Hyperactive Member
    Join Date
    Sep 2001
    Posts
    396
    if ( strlen(x) == xlen )

  4. #4
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    What if it's not a string? It could be a set of binary data in which case strlen() won't work.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  5. #5
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    Parksie is right. If its NULL, you have a problem, otherwise, continue. Heck, I usually only check for NULL in a utility function when it means something special. Otherwise, Ill check in the calling function before calling.

    Z.

  6. #6
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Under some implentations of the CRT, you can use some functions to check that a pointer is real (I believe the MS one has some debug implementations that can specifically validate a pointer).

    For anything else, you're going to have to do some poking around in the source for it.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  7. #7
    Fanatic Member nabeels786's Avatar
    Join Date
    Jul 2001
    Location
    New York
    Posts
    919
    sizeof() wont work?
    Visit www.fragblast.com
    Gaming, forums, and a online RPG/Battle system




    (__Flagg) DOT NET? is this a Hindi Dating service?

  8. #8
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    sizeof would return 4 on 32 bit implementations, and 8 on 64 bit implementations. Since a pointer is just a memory address, it has no idea of how much memory was originally allocated, or even if the pointer is valid anyway. For instance:
    Code:
    myFunc((char*)0x347624ff, 10);
    It looks JUST like a char* to the compiler... but it sure as hell wont work =).

    Z.

  9. #9

    Thread Starter
    Fanatic Member HaxSoft's Avatar
    Join Date
    May 2000
    Location
    Ohio
    Posts
    593
    OK ... In my case the pointer would usually point to a string, but it MIGHT point to something else, so that strlen() thing won't work always.

    Anyway, thank you all for your input; I appreciate it.

  10. #10
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    One way is to use assert() - it is either implemented as a macro or a function.

    Parksie is right - if the buffer is heap memory, only in Windows the long BEFORE the starting address of the buffer is the size of the buffer. Like BSTR. It's how free() knows how much memory is allocated.

    But this is NOT true if the buffer came from OLE or from VB, even if if it allocated memory dynamically like in ReDim. OLE & VB use descriptors in a descriptor table. OLE does use BSTR for string buffers. SO - just check for NULL, maybe in an assert. You cannot depend on anything else.

  11. #11
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    Well, Ive learned something today. Thanks jim! That is a potentially helpful tip =).

    Z.

  12. #12
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    The WinAPI contains three functions:
    IsValidReadPtr
    IsValidWritePtr
    IsValidExecPtr
    which can be used to verify the integrity of a pointer at runtime in a non-portable way.
    They don't return the size though, so if you don't know how the mem was allocated you can only cycle through the entire length of the array and call the above functions for each 4 byte chunk.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  13. #13

    Thread Starter
    Fanatic Member HaxSoft's Avatar
    Join Date
    May 2000
    Location
    Ohio
    Posts
    593
    Originally posted by CornedBee
    The WinAPI contains three functions:
    IsValidReadPtr
    IsValidWritePtr
    IsValidExecPtr
    which can be used to verify the integrity of a pointer at runtime in a non-portable way.
    They don't return the size though, so if you don't know how the mem was allocated you can only cycle through the entire length of the array and call the above functions for each 4 byte chunk.
    Hmm, I think I can live with this solution. Thanks!

  14. #14
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    Nope (as CB likes to say )

    Those are all macros, not directly WinAPI. What these do is to check sizeof(datatype) bytes for existence.

    It won't work for function pointers and some other things like void.

    Also: one way to do what you want without failure is to call the native Windows api using:

    MmIsAddressValid
    The MmIsAddressValid routine checks whether a page fault will occur for a read or write operation at a given virtual address.

    BOOLEAN
    MmIsAddressValid(
    IN PVOID VirtualAddress
    );
    Parameters
    VirtualAddress
    Points to the virtual address to check.
    Include
    ntddk.h

    Return Value
    If no page fault will occur from reading or writing at the given virtual address, MmIsAddressValid returns TRUE.
    It doesn't use length - it's purely bytes.

    See also the red stuff in this file:
    00001 // ==++==
    00002 //
    00003 //
    00004 // Copyright (c) 2002 Microsoft Corporation. All rights reserved.
    00005 //
    00029 #define COM_METHOD HRESULT STDMETHODCALLTYPE
    00030
    00031 inline HRESULT HrFromWin32(DWORD dwWin32Error)
    00032 {
    00033 return HRESULT_FROM_WIN32(dwWin32Error);
    00034 }
    00035
    00036 // Some helper #def's to safely Release, close & delete Objects under
    00037 // failure conditions
    00038
    00039 #define RELEASE(x) \
    00040 do \
    00041 { \
    00042 if (x) \
    00043 { \
    00044 IUnknown *punk = x; \
    00045 x = NULL; \
    00046 punk->Release(); \
    00047 } \
    00048 } while (0)
    00049
    00050
    00051 #define IfFailGo(expr) IfFailGoto(expr, Error)
    00052
    00053 #define IfFailGoto(expr, label) \
    00054 do { \
    00055 hr = (expr); \
    00056 if (FAILED (hr)) { \
    00074 // Good for memory allocations && verifying pointer parameters.
    00075 //
    00076
    00077 #define IfNullGo(expr) IfFalseGo((expr) != NULL, (E_OUTOFMEMORY))
    00078
    00079 //
    00080 // Check a boolean, condition jump to label 'Error'.
    00081 //
    00082
    00083 #define IfFalseGoto(_cond)\
    00084 do { \
    00085 if (!(_cond)) { \
    00086 goto Error; \
    00087 } \
    00088 } while (0)
    00089
    00090
    00091 #if _DEBUG
    00092 // ----------------------------------------------------------------------------
    00093 // Validation macros
    00094
    00095 #define IsValidReadPtr(ptr, type) !IsBadReadPtr((ptr), sizeof(type))
    00096
    00097 #define IsValidWritePtr(ptr, type) !IsBadWritePtr((ptr), sizeof(type))
    00098
    00099 #define IsValidReadBufferPtr(ptr, type, len) !IsBadReadPtr((ptr), sizeof(type) * (len))
    00100
    00101 #define IsValidWriteBufferPtr(ptr, type, len) !IsBadWritePtr((ptr), sizeof(type) * (len))
    00102
    00103 #define IsValidInterfacePtr(ptr, type) IsValidReadPtr(ptr, type)
    00104
    00105 #define IsValidCodePtr(ptr) !IsBadCodePtr((FARPROC)(ptr))
    00106
    00107 #define IsValidStringPtr(ptr) !IsBadStringPtr((ptr), 0xffffffff)
    00108
    00109 #define IsValidIID(iid) IsValidReadPtr(&(iid), IID)
    00110
    00111 #define IsValidCLSID(clsid) IsValidReadPtr(&(clsid), CLSID)

    00112 #else
    00113
    00114 #define IsValidReadPtr(ptr, type)
    00115 #define IsValidWritePtr(ptr, type)
    00116 #define IsValidReadBufferPtr(ptr, type, len)
    00117 #define IsValidWriteBufferPtr(ptr, type, len)
    00118 #define IsValidInterfacePtr(ptr, type)
    00119 #define IsValidCodePtr(ptr)
    00120 #define IsValidStringPtr(ptr)
    00121 #define IsValidIID(iid)
    00122 #define IsValidCLSID(clsid)
    00123
    00124 #endif
    00125
    00126 #endif

  15. #15
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Well, then IsBad* are functions I hope. Use those. Or the MM thing jim mentioned, although I never heard of it.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  16. #16
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    You might want to get a copy of the DDK - driver development kit.
    A lot of the API's we use are wrappers for native api.

  17. #17
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Doesn't surprise me. What good would a completly new set of functions be? Windows is already bloated enough.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  18. #18

    Thread Starter
    Fanatic Member HaxSoft's Avatar
    Join Date
    May 2000
    Location
    Ohio
    Posts
    593
    Hmm, it wasn't resolved ... Macros, macros, macros. I'll figure it out, though ... possible with the DDK.

    Incidentally, I have a totally different pointer question, which puzzles me. This time it involves Visual Basic...

    I have a DLL file, which I wrote in Visual C++ 5.0 (or 6.0, don't really remember). Anyway, it exposes a function called SwapInteger:

    Code:
    void APIENTRY SwapInteger(int *x,
                              int *y)
    {
        *x = *x ^ *y;  // swap values using xor...
        *y = *x ^ *y;
        *x = *x ^ *y;
    }
    Sometimes when I call the function from within the VB environment, I get really strange results. After compiling the VB exe file, it works just fine.

    Does anyone have a clue as to what might be wrong here? Is it just VB or is it me?

    The VB declaration is as follows:

    VB Code:
    1. Private Declare Sub SwapInteger _
    2.     Lib "haxutil.dll" ( _
    3.         ByRef x As Integer, _
    4.         ByRef y As Integer)

    It is not really a problem because I can compile the VB program and it works ... BUT I wonder why this happens. I don't like "lose ends" like this.

  19. #19
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    In 32-bit programming, an integer (int) is 32 bits. However, the VB Integer type is only 16.

    This causes the C code to mangle it along with the contents of the data *after* the Integer.

    Solution: Replace Integer with Long in your function call.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  20. #20

    Thread Starter
    Fanatic Member HaxSoft's Avatar
    Join Date
    May 2000
    Location
    Ohio
    Posts
    593
    OK, that makes sense. Thanks, man.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width