• Advertisement
Sign in to follow this  

Checking bad pointers

This topic is 4254 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Some pointer initialized would point to some address, and some un-initialized pointer would point to some bad address like 0xfdfdfdfd or 0xfefefefe etc. I want to check on run-time if a pointer has gone bad, while the only things that are checkable are:
if ( ptr == NULL ) // uninitialized
else
{
//ptr ok, proceed
}

this way, 0xfefefefe type bad pointers cannot be checked- so, is there a way to check that using ordinary pointers, and nothing fancy? Thank you.

Share this post


Link to post
Share on other sites
Advertisement
Generally speaking, the easiest way to deal with this is to simply set your pointers to NULL to initialize them and after you deallocate them. Many people use a macro for the latter, but it's completely possible to do in a function:

template<typename T>
void deallocate(T* x) {
delete x;
x = NULL;
}


If you're trying to find memory leaks because of bad pointers, there's a large amount of utilities out that for finding them, most of them being free. Googling for "memory leak find" turned up an interesting article on flipcode which uses a few custom memory tracking functions. Another search turned up an interesting leak finding tool, with source. I also seem to remember there being a few functions in visual c++ for finding leaks, as well, but can't remember the name offhand and google doesn't turn up anything.

Share this post


Link to post
Share on other sites
Quote:
Original post by bytecoder

template<typename T>
void deallocate(T* x) {
delete x;
x = NULL;
}



This function wouldn't work as you would expect, for instance if you do:

int * x = new int (15);
std::cout << "x == " << x << std::endl;
deallocate(x);
std::cout << "x == " << x << std::endl;

you would always see that in both cases x address is the same - NULL doesn't get assigned.
For the function to work, you'd have to pass the pointer by reference it like this:

template<typename T>
void deallocate(T* &x) {
delete x;
x = NULL;
}



Anyway, this function isn't very useful, because you'd need another one for array deallocation (delete[] operator). And you'd have to think carefuly because there would be problems if you'd confuse them.

Share this post


Link to post
Share on other sites
Thank you for the links, they will come in handy; but what I was trying to ask (did not mention this before) was that suppose I had initialized pointer to NULL, then with course of time, due to some programming erros, the pointer starts pointing towards some incorrect address, now at the momement i cannot think of a good reason why this would happen, but things like that may happen- programmer's mistake, so would there be some way to check if a pointer has gone bad?

Thank you.

Share this post


Link to post
Share on other sites
Quote:
Original post by Taha Ansari
Thank you for the links, they will come in handy; but what I was trying to ask (did not mention this before) was that suppose I had initialized pointer to NULL, then with course of time, due to some programming erros, the pointer starts pointing towards some incorrect address, now at the momement i cannot think of a good reason why this would happen, but things like that may happen- programmer's mistake, so would there be some way to check if a pointer has gone bad?

Thank you.


If you have a pointer that points to NULL, then it can not magicaly start pointing to something else. If you make sure you always assign NULL to all your uninitialized and deallocated (deleted) pointers - you won't have any problems.

Also, if in some place your code expects some pointer to be (or not to be) NULL, you can place an assert to ensure that. Then even if some other coder will be using that code - he will immediately see what he should do before using your code or he will get an assertion error (after which he will change his code).

My suggestion - don't worry so much about it. ;)

Edit: if you are using MSVC, then this might be interesting to you. Good luck.

Share this post


Link to post
Share on other sites
Quote:
Original post by Taha Ansari
Thank you for the links, they will come in handy; but what I was trying to ask (did not mention this before) was that suppose I had initialized pointer to NULL, then with course of time, due to some programming erros, the pointer starts pointing towards some incorrect address, now at the momement i cannot think of a good reason why this would happen, but things like that may happen- programmer's mistake, so would there be some way to check if a pointer has gone bad?

Thank you.
NO!
At best you may be able to determine if a pointer points to a valid page or something, or with some OS specific stuff you can check if it points into the heap or into the stack. But there is no reliable way to determine that a pointer is valid, or pointing to what you expect. You can sometimes determine that a pointer is definately NOT valid, but you cannot really determine when it IS valid.

Unfortunately, it really is up to your program to get it right. There are many C++ tools to help you get it right though, that you need to be aware of, and learn to use. For example, smart-pointers of varying types.[google]

Share this post


Link to post
Share on other sites
lol, I get the picture..i guess

1) assert is a good debug option
2) other options on that msdn link are worth a try-looks useful
3) smart pointers should be tried, I will google for them..

All your posts have been really helpful.

Thank you.

Share this post


Link to post
Share on other sites
Quote:
Original post by Taha Ansari
3) smart pointers should be tried, I will google for them..


[boost]

Share this post


Link to post
Share on other sites
Quote:
Original post by Fruny
Quote:
Original post by Taha Ansari
3) smart pointers should be tried, I will google for them..


[boost]


Isn't boost a big (30 Meg or so) library to be included...slowing things down a bit, or is it really worth it. I've heard too many people recommending it though...just dont like the idea of relying on other libraries....hmm.

Share this post


Link to post
Share on other sites
About the "smart pointers":

Check Google on "auto pointer"(autoptr) and "reference counted pointers".
The first one is one that destructs the data when the program leaves the scope and the second one is one that deletes the data when no piece of code uses the pointer anymore, so you don't have to delete the memory yourself in both cases.
In both cases, the the template classes make sure that a value is NULL or holds valid data(under certain conditions).

Check the download page of my COW project for a sample of an AutoPtr. It's in "\Source\COW\AutoPtr.h".
If I recall it correctly, the standard C++ libraries(or was it STL?) also holds an autoptr class.

Share this post


Link to post
Share on other sites
You only pay for what you use - that is, if you only use a couple of classes from boost, you only have the overhead of those classes in your final program. It's not like using boost::shared_ptr instantly adds 30MB to your .EXE file [wink]


In all frankness, you need to change your views on libraries. The C++ Standard Library is an absolute must (good freakin' luck writing a working C++ program without the C++SL or the legacy C libary). Boost is loaded with stuff that is so useful pretty much any nontrivial C++ program can benefit from at least one boost module - which is why a fair chunk of the library is being considered for official adoption into the standard library.

In general, using other libraries is not bad - quite the contrary, it's good. Reinventing wheels is wasteful, especially in today's world where so many wheels have already been invented and perfected. So many people work on code that it is extremely unlikely that you can do a better job than the collected efforts of dozens (maybe hundreds) of very smart people. Properly using libraries can do incredible wonders for your productivity, and for the power and reliability of your underlying code.


I will grant that it is useful to at least understand how/what your libraries do under the surface; sometimes, that means implementing some things yourself just to see what's involved. But in general you shouldn't use homebrew implementations when highly trusted and extremely reliable alternatives are available for free.

Share this post


Link to post
Share on other sites
Quote:
Original post by Taha Ansari
Isn't boost a big (30 Meg or so) library to be included...


Yes, the library itself is big. But NO the whole library doesn't get included into your program. Only the parts you do use are. Most of the library is contained in header files you include, just list the standard C++ library. A few components are compiled during installation, but this can be disabled if you prefer to explicitely compile them along with your program every time.

Quote:
slowing things down a bit


The only thing that may slow down is the compilation time. But that's where precompiled headers help.

Quote:
or is it really worth it.


Oh yes, it is really worth it.

Quote:
I've heard too many people recommending it though...


And with good reason.

Quote:
just dont like the idea of relying on other libraries....hmm.


You are suffering from the Not Invented Here Syndrome. Get over it as soon as possible. Yes, it does mean you will eventually have to learn how to deploy your applications properly, how to deal with DLLs and all that stuff.

<rant> But I guess people here make sure to write their own 3D graphics API and window manager rather than rely on Win32 and OpenGL or DirectX. For the few that dare use them, they obviously leave making sure all the right things are installed up to the hapless user of their game. </rant>

As for Boost itself, it's a de-facto standard collection of C++ libraries, the whole point being to extend the C++ standard library.

Share this post


Link to post
Share on other sites
Quote:
Original post by Taha Ansari
Isn't boost a big (30 Meg or so) library to be included...slowing things down a bit, or is it really worth it. I've heard too many people recommending it though...just dont like the idea of relying on other libraries....hmm.


Hehe. Boost, when you compile all configurations takes more than 1 GB on your hard drive... It also takes a lot of time to compile it (around 2 hours on my old machine).
So, yeah - it is a big library. On the other hand - it is the most useful thing i've ever seen.

By the way, if we are talking about useful libraries - loki is a must have (just like boost).

Share this post


Link to post
Share on other sites
Convinced with usage of boost, i'm trying to download that right now...I agree that its a must to be completely confident in using already invented libraries.. hope to see a difference soon.

by the way, i never got the precompiled headers to work the magic for me..

Thank you.

[edit:
Quote:
Hehe. Boost, when you compile all configurations takes more than 1 GB on your hard drive... It also takes a lot of time to compile it (around 2 hours on my old machine).
You must be kidding!

Share this post


Link to post
Share on other sites
Quote:
Original post by MaulingMonkey
Awesome, I didn't realize we had a forum code for that :)


It's brand new as of today.

Share this post


Link to post
Share on other sites
Quote:
Original post by Taha Ansari
[edit:
Quote:
Hehe. Boost, when you compile all configurations takes more than 1 GB on your hard drive... It also takes a lot of time to compile it (around 2 hours on my old machine).
You must be kidding!

He's not. But you don't need to compile everything, so size and time can be reduced.

Share this post


Link to post
Share on other sites
Quote:
Original post by Taha Ansari
...just dont like the idea of relying on other libraries....hmm.


You'll never get far in the industry with kind of thought besides that doesn't really make any sense because it is virtually impossible to not rely on any kind of library (be it third-party or not).

Share this post


Link to post
Share on other sites
Quote:
Original post by Brother Bob
Quote:
Original post by Taha Ansari
[edit:
Quote:
Hehe. Boost, when you compile all configurations takes more than 1 GB on your hard drive... It also takes a lot of time to compile it (around 2 hours on my old machine).
You must be kidding!

He's not. But you don't need to compile everything, so size and time can be reduced.

Yeah, i'm not kidding! :)
However, it is worth the space and the time it takes.

Offcourse, i could reduce the compile time and the size of compiled libraries (i only use 3-5 libraries right now). I guess i just like to have it all "just in case" (who knows which library i will need tomorow or 5 minutes later). ;)

Share this post


Link to post
Share on other sites
With this slow internet connection, only 83% of boost (something 1.3.1 .exe maybe) has been downloaded. Also on that page were available its source files and documentation files etc. Would those docs and source etc have to be downloaded as well along with the 9.71 MB .exe file (assumed to be self-extracting)? Hope not. Lets hope all those docs etc. are included in that .exe download.

Thank you

Share this post


Link to post
Share on other sites
Quote:
At best you may be able to determine if a pointer points to a valid page or something, or with some OS specific stuff you can check if it points into the heap or into the stack. But there is no reliable way to determine that a pointer is valid, or pointing to what you expect. You can sometimes determine that a pointer is definately NOT valid, but you cannot really determine when it IS valid.

Actually it is sometimes very useful to know if a pointer is potentially valid or completely bogus.
Consider a stack dumper and symbol engine. If you are disassembling code to reconstruct the preceding function's call site, you want to know if the resulting address is bad, to avoid tons of exceptions.
Also, when displaying local variables (which may or may not be initialized), you want to check if they're valid without spewing garbage at the address induced by current uninitialized pointer value.
What you can do (assuming IA-32 Windows)
- anything < 0x10000 is definitely no-go.
- anything > 0xC..0 (or 0x8..0 if /3GB is not active) is a kernel address, and inaccessible anyway.
- do *NOT* use IsBadReadPtr. that just accesses the memory whilst in a __try, so it can end up trashing your guard page (which is really really bad).
- to check for code pointers, reject addresses below GetModuleHandle(0). Calculating module size from PE header is overkill.
- stack pointers must be aligned and between the TIB's StackLimit and StackBase.

Share this post


Link to post
Share on other sites
Ok so boost is downloaded and installed... just a quick glance at it gives the impression that it could be very nice..

Quote:

What you can do (assuming IA-32 Windows)
- anything < 0x10000 is definitely no-go.
- anything > 0xC..0 (or 0x8..0 if /3GB is not active) is a kernel address, and inaccessible anyway.
- do *NOT* use IsBadReadPtr. that just accesses the memory whilst in a __try, so it can end up trashing your guard page (which is really really bad).
- to check for code pointers, reject addresses below GetModuleHandle(0). Calculating module size from PE header is overkill.
- stack pointers must be aligned and between the TIB's StackLimit and StackBase.


What you've said looks quite nice, though around half of what you said goes above the head. I understand that <0x100000 and 0xc..0 thing (but not 3GB), will give GetModuleHandle(0) a try, and...dont understand how to check if stack pointer is between StackLimit and StackBase ..

Share this post


Link to post
Share on other sites
3GB: the OS can be booted with the "/3GB" switch (google). If that's the case and the application advertises that it can handle pointers above 0x8..0 (i.e. doesn't do something stupid like middle = (p1+p2)/2), then the OS only reserves the topmost 1GB of virtual address space for itself.

Stack:
static NT_TIB* get_tib()
{
NT_TIB* tib;
__asm
{
mov eax, fs:[NT_TIB.Self]
mov [tib], eax
}
return tib;
}

bool debug_is_stack_ptr(void* p)
{
uintptr_t addr = (uintptr_t)p;
// totally invalid pointer
if(debug_is_pointer_bogus(p))
return false;
// not aligned
if(addr % sizeof(void*))
return false;
// out of bounds (note: IA-32 stack grows downwards)
NT_TIB* tib = get_tib();
if(!(tib->StackLimit < p && p < tib->StackBase))
return false;

return true;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by Paulius Maruska
Offcourse, i could reduce the compile time and the size of compiled libraries (i only use 3-5 libraries right now). I guess i just like to have it all "just in case" (who knows which library i will need tomorow or 5 minutes later). ;)

I was actually refering to the different link and runtime versions of all libraries. I'm only using the staticly linked multithreaded version, so no point building libraries with dynamic or singlethreaded runtime libraries. But yes, you can disable each library aswell if you don't need it to further reduce the time and size.

Actually, now I'm not even sure it compiles every combination or not by default. I just know it was one of the first thing I checked; how to build only the versions I need...

Share this post


Link to post
Share on other sites
Quote:
Original post by Jan Wassenberg
Quote:
At best you may be able to determine if a pointer points to a valid page or something, or with some OS specific stuff you can check if it points into the heap or into the stack. But there is no reliable way to determine that a pointer is valid, or pointing to what you expect. You can sometimes determine that a pointer is definately NOT valid, but you cannot really determine when it IS valid.

Actually it is sometimes very useful to know if a pointer is potentially valid or completely bogus.
Consider a stack dumper and symbol engine. If you are disassembling code to reconstruct the preceding function's call site, you want to know if the resulting address is bad, to avoid tons of exceptions.
Also, when displaying local variables (which may or may not be initialized), you want to check if they're valid without spewing garbage at the address induced by current uninitialized pointer value.
What you can do (assuming IA-32 Windows)
- anything < 0x10000 is definitely no-go.
- anything > 0xC..0 (or 0x8..0 if /3GB is not active) is a kernel address, and inaccessible anyway.
- do *NOT* use IsBadReadPtr. that just accesses the memory whilst in a __try, so it can end up trashing your guard page (which is really really bad).
- to check for code pointers, reject addresses below GetModuleHandle(0). Calculating module size from PE header is overkill.
- stack pointers must be aligned and between the TIB's StackLimit and StackBase.
Hmm, there goes a lot of that OS specific (or hardware specific) stuff I was talking about...[smile]
I knew about all that, but immediately giving that info seemed like handing a gun to a kid without any saftey training etc. Not to mention it suggests that using it would be the accepted thing to do in his case.
I'm sure you agree it is important to instill good habbits before showing how certain things could be done, if you really need to do them.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement