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

281 views Asked by At

In my function, a memory pointer and its size are passed as parameters:

int myFun(uintptr_t* mem_ptr, int mem_size) {
    // Code here
}

Is there any way to tell if this chunk of memory is really valid?

(The Operating System is CentOS Linux release 7.9.2009.)

2

There are 2 answers

0
Thomas On BEST ANSWER

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.

0
Goswin von Brederlow On

It's simple. Don't write such code.

It's prone to errors just like you want to check for. That's why modern c++ has invented for example std::span. A span represents a contiguous sequence of objects just like your pointer + size. But the pointer and size are not separate values that you can easily mix up in function calls. It's a single object containing both.

Actually if the size is known at compile time it gets encoded in the type itself and the span only contains a pointer making it smaller and allowing for better optimization of the function.

Beyond that you have to trust the users of your function don't lie to you. There is no good way to validate a pointer, a problem that hunts garbage collectors, and it's best to just let the OS tell you when the pointer is total garbage by producing a segfault.

Note: Using span instead of array makes is even simpler than passing pointer + size:

#include <span>

int get(std::span<int> x, size_t i) {
    return x[i];
}

int main() {
    int x[] = {2, 3, 5, 7, 11};
    return get(x, 2);
}

A std::span can be constructed from an array of known size so the compiler does all the work for you.