Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

pointers

I'm learning C++ and reading C++ Primer. There's a question I would like to know the answer:

Given a pointer p, can you determine whether p points to a valid object? If so, how? If not, why not?

like image 731
2013Asker Avatar asked Jun 19 '13 22:06

2013Asker


4 Answers

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.

like image 102
Kerrek SB Avatar answered Nov 18 '22 10:11

Kerrek SB


Not possible. Think of this scenario.

int *ptr = new int(10);
int *ptrDup = ptr;

delete ptr;

But ptrDup still points to the memory location pointed by ptr which no longer exists. So, deferencing ptrDup results undefined behavior. But there is reference counting which is totally a different concept.

like image 42
Mahesh Avatar answered Nov 18 '22 12:11

Mahesh


Not really possible to see if a pointer is "valid" in all it's meanings.

Sure, you can try to dereference the pointer (*ptr = x; or x = *ptr). If your code didn't crash, the pointer is pointing to valid memory. If it crashed, obviously, the pointer is no good. Unfortunately, this approach is a bit like checking if a gun is loaded by firing it at your head - which isn't the cleverest... Unfortunately, with pointers, there is no "check the chamber to see if it's loaded", so no real good way to figure out if the a pointer is valid, other than "if it doesn't cause an hardware fault, it's valid".

Note that this will only really tell you that "the pointer is pointing at some memory you can access" in most cases. It does NOT mean that the pointer "is correct for what you want it to be" (e.g. it points to the correct type). And it CERTAINLY won't tell you if the pointer is pointing to "stale data" (that is, when a pointer WAS valid, but it's now memory used for something else).

Unfortunately, with 232 or 264 [actually 248] possibly valid memory addresses in a modern system, it's almost impossible to know what addresses are valid and which ones are not. Even inside the operating system, the way the OS figures out if it can write to the memory you asked it to write to is "try to write it, see what happens". For the OS, this works out fine, because it can be careful about "this may go wrong, and if it does, I'll continue over there in the error recovery code". The OS has to deal with this because it has to accept, a) that programmers make mistakes, and b) that some people actually write malicious code to TRY to break the OS.

The way for an application to "make sure pointers are valid" is that the programmer writes code that is CAREFUL about what it stores in pointers, how it frees those pointers, and only use pointers that have valid values stored in them. You shouldn't end up "having to check whether the pointer is valid" - then you are "doing it wrong".

(When you work with a system for a while, and reading pointer values in a debugger, you do after a while recognise "good" and "bad" pointers - but that's just because you learn what, usually, a good pointer vs. a bad pointer looks like. To write code to recognise such is almost impossible - especially if the system is allocating a lot of memory, so it uses most of the available space.)

Of course, in C++, there are smart pointers, vectors, and various other tools that mean a lot of the time you don't even have to bother with pointers. But understanding how to use pointers and how pointers work is still a good thing to do.

like image 10
Mats Petersson Avatar answered Nov 18 '22 12:11

Mats Petersson


If a pointer is set to nullptr, that means it hasn't been given an object to point to and instead has been given a "default" value. It's possible that the pointer could not be assigned to nullptr and at the same time not be assigned to a valid object, but in that case it would be impossible to determine that. For example:

With nullptr:

int *ptr = nullptr;

// check if pointer is unassigned to an object
if (ptr == nullptr) ptr = new int{0};

Without nullptr:

int *ptr;

// using ptr while uninitialized is Undefined Behavior!
if (ptr != &some_object)
like image 4
David G Avatar answered Nov 18 '22 10:11

David G