Grady Player
Grady Player

Reputation: 14549

Is there a way in std C to tell if I can dereference a pointer safely

consider the following:

int * i = malloc(sizeof(int));
free(i);

I am now in a scenario where i points to deallocated memory, but it is also non-zero; this is a common error in C programming, is there a way to tell that i is still a valid pointer before I go and do something like:

*i++; //probable EXC_BAD_ACCESS crash

I know that it is completely impossible for there to be a 100% reliable (no false positives) method, unless you never reused memory; but something that worked most of the time would be great for debugging.

edit

I am not arguing that you shouldn't set your pointers to NULL, I am just wondering if there is a portable (POSIXish) way to poke an address without catastrophic repercussions, I just have an interest in debugging complicated multithreaded problems that arise from time to time.

Upvotes: 2

Views: 309

Answers (5)

ouah
ouah

Reputation: 145899

Some people like to set the freed pointer to NULL right after free:

#define paranoid_free(ptr)    (free(ptr), (ptr) = NULL)

This has the advantage to avoid double-free issue as free(NULL) is defined in C (as a no-operation). But it will still not prevent you to dereference the pointer and invoke undefined behavior elsewhere in your program.

Upvotes: 0

justin
justin

Reputation: 104698

No.

Static analysis and live tools (e.g. valgrind and guard malloc) can help you with this problem. Altering the way you approach writing programs also helps understand ownership and lifetimes more easily.

If you really wanted this functionality in more detail, you could use a custom allocator -- but there are tools in existence which help greatly.

Upvotes: 2

John Bode
John Bode

Reputation: 123558

There's no (portable) way to know if a non-NULL pointer value is valid from the pointer value itself. Similarly, there's no (portable) way to know if the pointer points to an object with auto, static, or dynamic extent. If you're intimately familiar with your platform's memory model you could probably make some educated guesses (i.e., 0x00000001 is probably not a valid memory location), but that's about it.

You'll have to track all that information separately from the pointer itself, or enforce some discipline in how you use pointers.

Upvotes: 1

Edmund
Edmund

Reputation: 10819

All you can really do in C is pass around enough information to know whether i still points to something.

Philosophically, if you don't know at the point of *i++; whether i still points to something that can be safely incremented, how do you know its correct to increment it even if it does?

It's a similar situation to array usage in C: you get into the habit of passing around both a pointer to the data, and an accompanying size indicator. Or you wrap both of them into a structure.

Perhaps if you can give a larger example of how i is used, people can recommend an idiomatic way of adding the additional information you need at the deference point.

Upvotes: 0

dbeer
dbeer

Reputation: 7213

To get something that works for debugging you want to use valgrind's memcheck tool. You'll see an invalid read or an invalid write error when the access happens.

@Anthales is right, you need to set the pointer to NULL as soon as you free. If you have multiple references to the pointer, this gets more complicated. Without knowing the specifics of your situation, I can't say exactly how to do this, but a possible solution can be giving the different structs something that allows them to request the reference to that memory instead of a specific pointer.

Upvotes: 2

Related Questions