By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,750 Members | 1,221 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,750 IT Pros & Developers. It's quick & easy.

Memory (read) access violation handling in C

P: n/a
I have a structure defined like this:

struct foo
{
unsigned int magic ;
void *mydata ;
};

I have macros and defines like this :

#define MAGIC (0xFABF00D)
#define ISVALID_PTR(ptr) if(ptr)((ptr)->magic == MAGIC) ? 1 : 0) \ else 0

When a "bad pointer" - ( an arbitrary integer for example) is passed to
the macro, my library crashes (as one may well expect).

I am providing this C interface into another language, where there is a
great possibility of misuse and integers may be passed (accidentally) to
my functions, which use this validation macro above. I want my library
to be robust in the presence of such errors - in otherwords, I need to
be able to handle memory (READ) access violations gracefully and to be
able to recover from them - it is fairly trivial to do this in C++, but
I can't seem to find a way to do this in C.

Any solutions ?

Jun 18 '06 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Bit byte wrote:
#define ISVALID_PTR(ptr) if(ptr)((ptr)->magic == MAGIC) ? 1 : 0)


That macro can't do anything.
It's part of an if statement, so it has no value,
and the statement has no side effects.
I would write that, this way:

#define ISVALID_PTR(ptr) (ptr != NULL && ptr -> magic == MAGIC)
--
pete
Jun 18 '06 #2

P: n/a
Bit byte <fl**@flop.com> writes:
I have a structure defined like this:

struct foo
{
unsigned int magic ;
void *mydata ;
};

I have macros and defines like this :

#define MAGIC (0xFABF00D)
#define ISVALID_PTR(ptr) if(ptr)((ptr)->magic == MAGIC) ? 1 : 0) \ else 0

When a "bad pointer" - ( an arbitrary integer for example) is passed
to the macro, my library crashes (as one may well expect).

I am providing this C interface into another language, where there is
a great possibility of misuse and integers may be passed
(accidentally) to my functions, which use this validation macro
above. I want my library to be robust in the presence of such errors -
in otherwords, I need to be able to handle memory (READ) access
violations gracefully and to be able to recover from them - it is
fairly trivial to do this in C++, but I can't seem to find a way to do
this in C.


There's no way in C to test whether a pointer is valid. You can
easily test whether a pointer is null, but if it's non-null garbage,
any attempt even to look at its value invokes undefined behavior.

<OT>I'm surprised that C++ provides a way to detect this; I would have
thought it also says this is undefined behavior.</OT>

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 18 '06 #3

P: n/a

Bit byte wrote:
I have a structure defined like this:

struct foo
{
unsigned int magic ;
void *mydata ;
};

I have macros and defines like this :

#define MAGIC (0xFABF00D)
#define ISVALID_PTR(ptr) if(ptr)((ptr)->magic == MAGIC) ? 1 : 0) \ else 0

When a "bad pointer" - ( an arbitrary integer for example) is passed to
the macro, my library crashes (as one may well expect).

I am providing this C interface into another language, where there is a
great possibility of misuse and integers may be passed (accidentally) to
my functions, which use this validation macro above. I want my library
to be robust in the presence of such errors - in otherwords, I need to
be able to handle memory (READ) access violations gracefully and to be
able to recover from them - it is fairly trivial to do this in C++, but
I can't seem to find a way to do this in C.

Any solutions ?


An arbitrary integer may happen to have a valid value for a pointer. So
I
don't think that there is a completely reliable way to check whether a
pointer
points to garbage. But if your concern is to check whether a pointer
points
to an area of memory from which your programme is not allowed to read
then the only possible **non-standard/non-portable** solution I can
think of is the following: it may be that your operating system sends
some
specific signal to a programme if it tries to read from memory it is
not
supposed to access. If this is the case then you should be able to do
something
useful using the signal() function. So I would suggest that you check
your
operating system's documentation.

Jun 18 '06 #4

P: n/a
On Sun, 18 Jun 2006 19:56:45 GMT, Keith Thompson <ks***@mib.org>
wrote:
Bit byte <fl**@flop.com> writes:
I am providing this C interface into another language, where there is
a great possibility of misuse and integers may be passed
(accidentally) to my functions, which use this validation macro
above. I want my library to be robust in the presence of such errors -
in otherwords, I need to be able to handle memory (READ) access
violations gracefully and to be able to recover from them - it is
fairly trivial to do this in C++, but I can't seem to find a way to do
this in C.


There's no way in C to test whether a pointer is valid. You can
easily test whether a pointer is null, but if it's non-null garbage,
any attempt even to look at its value invokes undefined behavior.

Not in standard C, the topic here. However, the conversion from
pointer types to (suitable) integers is nonnormatively "intended to
be consistent with the addressing structure of the execution
environment" and on all or nearly so platforms even indeterminate or
dangling pointers do give _some_ value which can usefully be analyzed
but only in a platform-dependent way.
<OT>I'm surprised that C++ provides a way to detect this; I would have
thought it also says this is undefined behavior.</OT>


Standard C++ does not. It does however provide syntax and mechanism
for exceptions, and _some_ implementations which are able to catch
invalid memory accesses, or other 'hardware' faults like zerodivide,
choose to have them raise platform-defined exceptions -- which can
then be handled using basically standard constructs.

_On these platforms_ using (standard C) signal() to establish a
handler for SIGSEGV or similar is very likely to work as well.

As already noted this is only a half-measure; on almost all systems it
is trivial to construct, and often easy to get by accident, pointer
values which don't cause an immediate fault but are nonetheless
invalid and when used cause horribly bad results. (I once had a really
bad Heisenbug of this type; if the program was run under the debugger
the invalid pointer it used happened to be benign, but if run without
the debugger it got a different invalid pointer which caused a crash.)

- David.Thompson1 at worldnet.att.net
Jun 26 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.