C++ How to Determine Whether a Pointer Points to a Valid Object

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.

Check if a pointer points to a valid structure

You can only check if pointer is valid by doing pointer != NULL because anything except `NULL' is treated by valid pointer.

In your case, to check if your pointer points to any of your array entry, you can only do this:

size_t i = 0;
int isValid = 0;
for (i = 0; i < N; i++) {
if (test_ptr == &array[i]) {
isValid = 1;
break;
}
}

if (isValid) {
//Pointer points to one of your array entry
}

But in general, you cannot just test if pointer points to specific valid location for you. It is up to you to take care of where it points. It can also have NON-NULL value but points to invalid location, for example:

int* ptr = malloc(10); //Now points to allocated memory
*ptr = 10;
free(ptr); //Free memory
*ptr = 10; //Undefined behaviour, it still points to the same address but
//we don't know what will happen. Depends on implementation

Is it possible to determine if a pointer points to a valid object, and if so how?

Is it possible to determine if a pointer points to a valid object

No, it isn't generally possible to determine whether a pointer points to a valid object.

I wanted to know if anything has changed

Nothing has changed in this regard.

I read that with smart pointers that would be possible. So how could that be achieved?

Unless you misuse it in a bad way, a smart pointer is never invalid. As such, there is no need to check whether it is valid or not. It should either be null or point to a valid object.

Weak pointer is a special kind of smart pointer that doesn't own an object directly, but it points to an object owned by shared pointer(s). The pointed object may be destroyed when no shared pointer points to it anymore. It's possible to ask the weak pointer whether that has happened or not. This state is somewhat analogous to being invalid, except the state is verifiable.

So how could that be achieved?

You can std::make_unique or std::make_shared to create a dynamic object owned by a smart pointer. The choice between them depends on what kind of ownership you need: unique or shared. Weak pointers can be created only from shared pointers.

How to check if a pointer still points to valid memory in C++?

Use a shared_ptr<T> combined with a weak_ptr<T>.

For example,

int main() {
std::tr1::shared_ptr<int> ptr0(new int);
std::tr1::weak_ptr<int> ptr1_weak(ptr0);

*ptr0 = 50;

// Depending on if you reset or not the code below will execute
//ptr0.reset();

if (std::tr1::shared_ptr<int> ptr1 = ptr1_weak.lock()) {
std::cout << "Changing value!" << std::endl;
*ptr1 = 500;
}
}

Nullptr and checking if a pointer points to a valid object

In C, anything that's not 0 is true. So, you certainly can use:

if (ptrToObject) 
ptrToObject->doSomething();

to safely dereference pointers.

C++11 changes the game a bit, nullptr_t is a type of which nullptr is an instance; the representation of nullptr_t is implementation specific. So a compiler may define nullptr_t however it wants. It need only make sure it can enforce proper restriction on the casting of a nullptr_t to different types--of which boolean is allowed--and make sure it can distinguish between a nullptr_t and 0.

So nullptr will be properly and implicitly cast to the boolean false so long as the compiler follows the C++11 language specification. And the above snippet still works.

If you delete a referenced object, nothing changes.

delete ptrToObject;
assert(ptrToObject);
ptrToObject = nullptr;
assert(!ptrToObject);

Because of how long I have been writing these ifs like this, it is second nature at this point to check if the pointers valid before using by typing if (object *) and then calling it's members.

No. Please maintain a proper graph of objects (preferably using unique/smart pointers). As pointed out, there's no way to determine if a pointer that is not nullptr points to a valid object or not. The onus is on you to maintain the lifecycle anyway.. this is why the pointer wrappers exist in the first place.

In fact, because the life-cycle of shared and weak pointers are well defined, they have syntactic sugar that lets you use them the way you want to use bare pointers, where valid pointers have a value and all others are nullptr:

Shared

#include <iostream>
#include <memory>

void report(std::shared_ptr<int> ptr)
{
if (ptr) {
std::cout << "*ptr=" << *ptr << "\n";
} else {
std::cout << "ptr is not a valid pointer.\n";
}
}

int main()
{
std::shared_ptr<int> ptr;
report(ptr);

ptr = std::make_shared<int>(7);
report(ptr);
}

Weak

#include <iostream>
#include <memory>

void observe(std::weak_ptr<int> weak)
{
if (auto observe = weak.lock()) {
std::cout << "\tobserve() able to lock weak_ptr<>, value=" << *observe << "\n";
} else {
std::cout << "\tobserve() unable to lock weak_ptr<>\n";
}
}

int main()
{
std::weak_ptr<int> weak;
std::cout << "weak_ptr<> not yet initialized\n";
observe(weak);

{
auto shared = std::make_shared<int>(42);
weak = shared;
std::cout << "weak_ptr<> initialized with shared_ptr.\n";
observe(weak);
}

std::cout << "shared_ptr<> has been destructed due to scope exit.\n";
observe(weak);
}

Now, will C++ do the same for pointers? If pass in a char * like this to an if statement?

So to answer the question: with bare pointers, no. With wrapped pointers, yes.

Wrap your pointers, folks.

How to check if a pointer is valid in C++?

Memory managers do tend to be closer to the hardware level and may need to make decisions based on the operating system and CPU type they're used on.

In this case you may be able to justify breaking some of the C++ abstract machine rules. For example, just go ahead and compare your pointer with the boundaries of your pool array. Yes, this can go wrong on architectures that use segmented memory or that can form trap pointers, but what else are you going to do?

After that, to validate that you have a proper pointer you can have your allocator write a magic value into the allocation header block, which you can verify in the deallocate function before you start writing into free booleans and free block pointers, etc.

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.

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.

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