Testing Pointers For Validity (C/C++)

Testing pointers for validity (C/C++)

Update for clarification: The problem is not with stale, freed or uninitialized pointers; instead, I'm implementing an API that takes pointers from the caller (like a pointer to a string, a file handle, etc.). The caller can send (in purpose or by mistake) an invalid value as the pointer. How do I prevent a crash?

You can't make that check. There is simply no way you can check whether a pointer is "valid". You have to trust that when people use a function that takes a pointer, those people know what they are doing. If they pass you 0x4211 as a pointer value, then you have to trust it points to address 0x4211. And if they "accidentally" hit an object, then even if you would use some scary operation system function (IsValidPtr or whatever), you would still slip into a bug and not fail fast.

Start using null pointers for signaling this kind of thing and tell the user of your library that they should not use pointers if they tend to accidentally pass invalid pointers, seriously :)

How to check if a pointer is valid?

The best bet if you must use raw pointers is to make sure that it is either a valid pointer or NULL. Then you can check if it is valid by checking if it is equal to NULL.

But to answer your question, you can catch these kinds of things with structured exception handling (SEH).

That being said, SEH is a bad idea.

testing for valid pointer in c++

*p = 0;  

you probably meant

p = 0;

*p = 0 sets what the pointer points to, not the pointer

C++ Is it possible to determine whether a pointer points to a valid object?

No, you can't. Why? Because it would be expensive to maintain meta data about what constitutes a valid pointer and what doesn't, and in C++ you don't pay for what you don't want.

And you don't want to check whether a pointer is valid, because you know where a pointer comes from, either because it's a private part of your code that you control, or because you specified it in your external-facing contracts.

How to check pointer points to valid String in C

You cannot do this.

You can determine whether a char* value is a null pointer or not, but if it's non-null, you cannot determine whether it's a valid pointer. You certainly can't do so portably; you probably can't do it non-portably either.

For example:

char *ptr = malloc(6);
strcpy(ptr, "hello");
// now ptr points to a valid string
free(ptr);
// now ptr doesn't point to a valid string -- but there's no way to test it

If you happen to know that the pointer is valid (or is either valid or null), you still can't do it. For example:

char buf[5] = "hello"; // not a string, since there's no '\0'
char *ptr = buf; // ptr points to valid data, but it's not a string

You can scan memory starting at *ptr looking for a '\0' string terminator, but you can't know when to stop looking. In this case, you might look at 5 bytes of memory and not find a '\0' -- but what if ptr pointed to a valid string that's 1000 characters long?

And in this case, it's entirely possible that there happens to be a '\0' byte immediately after the array, which could make it appear that ptr points to a valid string. (Accessing that 6th byte has undefined behavior. The worst consequence of undefined behavior is that it can appear to "work", which just means it's more difficult to track down the bug.)

The only way to determine whether a pointer points to a valid string is to write your code in a way that guarantees that it does. If it doesn't, it's not a problem you can detect after it occurred.

Can we check a pointer to make sure it is a valid address?

I think a valid pointer should have a valid object.

Yes, that's the definition of a valid pointer.

If we try to print out the object we verify if the pointer is valid.

Unfortunately, you can't. You can check whether the pointer is null; but if it wasn't initialised properly, or if it pointed to an object that's been destroyed, it will be neither valid nor null.

If you want a pointer that's smart enough to know whether it's valid, you'll need a smart pointer.

Fast way to check if file pointer points to a valid file

If a call to fopen has succeeded, but you want to know whether you've just opened a file or something else, I know of two general approaches:

  1. Use fstat on the file descriptor (or stat on the same pathname you just opened), then inspect the mode bits.

  2. Attempt to seek on the file descriptor. If this works as expected it's probably a file; if it doesn't it's a pipe or a socket or something like that.

The code for (1) might look like

struct stat st;
fstat(fileno(fp), &st);
if(st.st_mode & S_IFMT) == S_IFREG)
/* it's a regular file */

To perform (2) I normally seek to offset 1, then test to see what offset I'm at. If I'm at 1, it's a seekable file, and I rewind to 0 for the rest of the program. But if I'm still at 0, it's not a seekable file. (And of course I do this once, right after I open the file, and record the result in my own flag associated with the open file, so the performance hit is minimal.)

How to judge whether the incoming buffer is valid in C++?

Don't. Just don't.

Even if you could find a way to check whether the pointer can safely be dereferenced, that doesn't mean it points where you think it does! It might point into your call stack, into your read-only code segment, into the static variables of some library that you're using, or any other place in memory that your program happens to have access to.

The responsibility of passing a valid pointer should be with the caller of the function. To make it harder for the caller to do something stupid, consider passing a std::vector & or std::vector const & instead.



Related Topics



Leave a reply



Submit