01 January 2007

Yesterday, a colleague was confronted with a core dump caused by NULL pointer. But this case was a little unusual and she was confused. Like her, many people know that accessing address 0x0 (NULL pointer) is illegal and causes core dump (segment fault). What they do not know is that using NULL pointer does not necessarily always cause core dump immediately. Sometimes, there is even no core dump. Here is the example illustrates that.

void f2(C* pc) {
    // ...
    expression(pc->m); // * <=== the spot when core dump happened
    // ...
}

void f1(){
    // ...
    f2( &(pa->pb->c) ); // **
    // ...
}

struct A{
    // ...
    struct B* pb;
    // ...
};

struct B{
    // ...
    C c;
    // ...
}

The core file shows that the process crashes in function f2. It seems that the de-referencing pointer pc caused the core dump. But, the value of pc is not NULL but 0x38. Instead, pb was NULL. This confused my colleague since she thought the process should have cored in f1.

This is a common misunderstanding. Please note that code like &(p->m) does not access the member m of p. It just only get the address of m. In c programming language, this is achieved by adding up the address of p and the offset of m within the structure. Therefore, it does not matter if the address p is NULL or not. In fact, it is a widely used technique to get the offset of structure members as shown below:

(int) (&(((X *)NULLP)->Y))

On the other hand, once we find a pointer points to a very small address (no bigger than structure size) we can be pretty sure that NULL pointer is used (either intentionally or inadvertently).



blog comments powered by Disqus