Reputation: 1326
Example.
If I have a pointer,
int* p;
p = (int*)2; // just for test
*p = 3; // it will be crack, right?
In general, the access of the pointer of value 2 will be crack. But actually the crack is not so simple. Invalid value of the pointer maybe comes from the Runtime error. I'd like to find a way to check the pointer before accessing it.
Upvotes: 2
Views: 189
Reputation: 1
In standard C99, this (dereferencing (int*)2
in your *p =3;
statement) is undefined behavior (UB). Read C.Lattner's blog on that. You should be very scared of UB. This is why programming in C is so hard (other programming languages like Ocaml, Common Lisp have much less UB).
A C program may have undefined behavior but might not always crash.
In practice, when coding in C, be vary careful about pointers. Initialize all of them explicitly (often to NULL
). Be very careful about pointer arithmetic. Avoid buffer overflows and memory leaks. Static source code analysis may help (e.g. with Frama-C) but is limited (read about halting problem & Rice's theorem). You could use quite often flexible array members and check pointers and indexes at runtime.
On some embedded freestanding C implementations (e.g. coding for Arduino like devices), some addresses might have particular meanings (e.g. be some physical IO devices), hence UB could be very scary.
(I am focusing on Linux below)
On some implementations, and some operating systems, you might test if an address is valid. For example on Linux you might parse /proc/self/maps
to compute if some given address is valid (see proc(5) for more about /proc/
).
(therefore, you could write -on Linux- some function bool isreadableaddress(void*)
which would parse /proc/self/maps
and tell if an address is readable in the virtual address space of your process; but it won't be very efficient since needing several system calls)
And you should use valgrind and compile with all warnings & debug options (gcc -Wall -Wextra -g
) and use the debugger (gdb
) and some more debugging compiler options like -fsanitize=address
You might perhaps handle the SIGSEGV
signal, but it is very tricky and highly non-portable (operating system, processor, and ABI specific). Unless you are a guru, you should not even try.
Upvotes: 6
Reputation: 8099
Actually it is possible... sort of....
Not with plain C, but most environments allow you to test whether a you can write to a pointer...
Unfortunately you have no way of knowing if a pointer points at what you intend. Meaning you can be pointing at another valid address, different from what you expect, and unintentionally corrupt a piece of your own memory...
char a[2];
int b; // assuming they are stored on the stack sequentially and aligned one right after the other...
char *ptr = (char*)a;
ptr += 3;
*ptr = 'b' // valid pointer, but probably an error....
Upvotes: 0
Reputation: 385295
Yes, "it will be crack".
Your program has no way to know whether an arbitrarily-initialised pointer will practically "work" at runtime. Firstly, you compile your code before you run it, potentially on a completely different computer. The compiler cannot predict the future.
The language deals with this by saying any pointer not explicitly made to point to an object or array that you created in the program cannot exist as long as you want your program to have well-defined behaviour.
Basically, the only way to be sure is to not do this.
Upvotes: 3