|
-
Sep 22nd, 2002, 04:17 AM
#1
Thread Starter
Fanatic Member
[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.
-
Sep 22nd, 2002, 04:41 AM
#2
Monday Morning Lunatic
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
-
Sep 22nd, 2002, 05:21 AM
#3
Hyperactive Member
if ( strlen(x) == xlen )
-
Sep 22nd, 2002, 07:07 AM
#4
Monday Morning Lunatic
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
-
Sep 22nd, 2002, 10:08 AM
#5
Frenzied Member
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.
-
Sep 22nd, 2002, 10:12 AM
#6
Monday Morning Lunatic
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
-
Sep 22nd, 2002, 10:53 AM
#7
Fanatic Member
Visit www.fragblast.com
Gaming, forums, and a online RPG/Battle system
(__Flagg) DOT NET? is this a Hindi Dating service?
-
Sep 22nd, 2002, 10:58 AM
#8
Frenzied Member
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.
-
Sep 22nd, 2002, 02:31 PM
#9
Thread Starter
Fanatic Member
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.
-
Sep 23rd, 2002, 09:10 AM
#10
Frenzied Member
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.
-
Sep 23rd, 2002, 12:25 PM
#11
Frenzied Member
Well, Ive learned something today. Thanks jim! That is a potentially helpful tip =).
Z.
-
Sep 24th, 2002, 06:54 AM
#12
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.
-
Sep 25th, 2002, 04:14 PM
#13
Thread Starter
Fanatic Member
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!
-
Sep 25th, 2002, 05:26 PM
#14
Frenzied Member
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
-
Sep 26th, 2002, 02:57 AM
#15
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.
-
Sep 26th, 2002, 08:45 PM
#16
Frenzied Member
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.
-
Sep 27th, 2002, 02:37 AM
#17
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.
-
Sep 27th, 2002, 11:35 AM
#18
Thread Starter
Fanatic Member
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:
Private Declare Sub SwapInteger _
Lib "haxutil.dll" ( _
ByRef x As Integer, _
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.
-
Sep 27th, 2002, 11:53 AM
#19
Monday Morning Lunatic
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
-
Sep 27th, 2002, 03:35 PM
#20
Thread Starter
Fanatic Member
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|