-4

What is an example of an application that requires the use of a null pointer for proper execution? Simply checking for null pointers and doing testing does not count. This example is supposed to be "commonly used" by C programmers.

After some more thought I have one possible example but I don't want to influence the responses (yet).

Edit: This question was an interview for a programming job that requires knowledge but not godlike skills in C. The answer is not going to be some esoteric aspect of the language.

Adam27X
  • 889
  • 1
  • 7
  • 16
  • What do you mean? Like dereferencing `NULL` is supposed to do something? – Carl Norum Jan 17 '13 at 22:14
  • An application as in a program? Or a (library) function that takes `NULL` as a valid argument? – Theodoros Chatzigiannakis Jan 17 '13 at 22:14
  • @CarlNorum Not necessarily dereferencing `NULL` but using a `NULL` pointer in some way. @TheodorosChatzigiannakis A program. – Adam27X Jan 17 '13 at 22:17
  • 2
    So what's your point in asking this anyway? – netcoder Jan 17 '13 at 22:18
  • 2
    @Adam27X - "simply checking for null pointers... does not count". If you can't check that a pointer is null, what else could you possibly do with it? – detly Jan 17 '13 at 22:18
  • 1
    Does using `NULL` to initialise arrays of pointers count? – Daniel Fischer Jan 17 '13 at 22:18
  • @netcoder The person interviewing me implied that is was a common case and if something like this is common knowledge, I'd like to know. – Adam27X Jan 17 '13 at 22:22
  • 1
    The whole point of NULL is that it is the only value that the compiler guarantees will NOT be assigned to you as a valid memory address. So the interview question is strange, in that NULL is always required for proper program execution. So you ought to be able to take any common case involving the use of pointers, whether it's a simple test or not. – paddy Jan 17 '13 at 22:51
  • The *only* things you can validly do with a null pointer are copy it and check it for equality against other pointers (including another null pointer). Copying it is just delaying the "real" use until later. So if "checking for null pointers" isn't allowed, the only thing left is what paddy says above, that a null pointer has the property that it doesn't compare equal to the address of any object. – Steve Jessop Jan 18 '13 at 00:52

6 Answers6

6

execvp family functions expect the argument list to be terminated with a null pointer. For example,

 execvp("/bin/ls", arguments);

Here arguments should end with NULL.

P.P
  • 117,907
  • 20
  • 175
  • 238
  • 1
    Isn't that just "checking for null pointers and doing testing"? I mean, that's what happens inside `execvp` - the `NULL` is just a sentinel. Maybe I'm misundertanding the question. – Carl Norum Jan 17 '13 at 22:22
  • 3
    @CarlNorum: It's more like using a null pointer as a terminator for a variable-length array. – Kerrek SB Jan 17 '13 at 22:22
  • While this isn't wrong, it's certainly not the answer the interviewer was looking for. See my edit. The answer is a common, well-known usage of NULL pointers. – Adam27X Jan 17 '13 at 22:26
  • 3
    @Adam27X You're making this question into one of those frustrating lateral thinking puzzles, except hinging on even finer points of semantics. Do you want an answer to it as stated, or do you want the one answer you're thinking of? – millimoose Jan 17 '13 at 22:28
  • @millimoose I want the answer my interviewer was thinking of, which certainly wasn't this answer. Making people guess what I'm thinking of is a waste of time and my example is possibly also a case of "testing" but I'll go ahead and post it. – Adam27X Jan 17 '13 at 22:30
  • 3
    @Adam27X How is having people guess what you're thinking different from having them guess what the interviewer was thinking? I'm really not sure this question is answerable. – millimoose Jan 17 '13 at 22:31
  • @millimoose I was assuming a lack of knowledge of something obvious on my behalf but after seeing the responses here I certainly don't feel as bad about it anymore. – Adam27X Jan 17 '13 at 22:34
  • @KerrekSB, yes, that's exactly what it is. And the loop inside `execvp` is just iterating and testing for that null-termination. – Carl Norum Jan 17 '13 at 22:39
  • 4
    @Adam27X Then your interviewer was being abstruse. (A good rule of thumb for telling whether an interview question is dumb is that it'd get closed on SO.) – millimoose Jan 17 '13 at 22:40
  • @millimoose: that's an awful rule of thumb, since interview questions that "solicit debate, arguments and extended dicussion" are often the most useful for finding out how someone thinks about programming ;-) – Steve Jessop Jan 18 '13 at 00:48
6

The function strtok() depends on NULL for second and subsequent iterations; so do its better behaved relatives strtok_r() and strtok_s().


Slightly different emphasis:

  • String search functions such as strchr() and strstr() return NULL pointers when they can't find what you asked them to look for.

  • The memory allocation functions return NULL pointers when the allocation fails.

  • The fopen() function returns a NULL pointer when it fails to open the file.

  • The opendir() function returns a NULL pointer when it fails to open a directory.

Notice a theme here? A NULL pointer is often returned as an error indication. Whether that counts as 'just checking' or not is perhaps more debatable.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • I was also asked if we need to check anything after using `malloc()` so this could definitely be on the right track. – Adam27X Jan 17 '13 at 22:30
2

Linked lists.

struct node
{
   int data;
   node* next;
}

The last pointer always has to be NULL, right? If it isn't, the program wouldn't execute properly. This could still count as testing, but it is required for proper program execution. Thoughts?

Adam27X
  • 889
  • 1
  • 7
  • 16
  • 3
    It's not exactly *necessary*. While it's true that it's common usage, any other sort of flag would work. – netcoder Jan 17 '13 at 22:35
  • 1
    This answer is essentially identical to @KingsIndian's answer. His example uses the NULL for variable-length array termination. This one uses it for a list, but neither *needs* to. – Carl Norum Jan 17 '13 at 22:41
  • IIRC, [Sedgewick's linked list implementation in C++](http://www.amazon.com/Algorithms-Parts-1-4-Fundamentals-Structure/dp/0201350882) (not this version, but 2nd edition, I think. Maybe it's still implemented the same.) allocated an end node (which pointed to itself in `next`) that was the end of the list. – ldav1s Jan 17 '13 at 22:56
  • You can have a circular linked list where the tail node points to the head node, and no pointer is null (except when the list is empty). – Jonathan Leffler Jan 18 '13 at 01:21
0

The NULL value is clearly very useful to indicate "the end of" or "non-existance of" some value. Optionial arguments in functions are indicated by NULL, for example. Or "it hasn't been allocated yet...".

But a NULL value is not useful as a reference, it is never right to use NULL value for anything other than comparison, or assignment when your pointer is not needed [obviously, assuming it has been freed properly].

I am working on a piece of code that runs early on in the operating system boot - in later running of the code, it needs to have the current task in some places. But before the system has started properly, there is no current task. So I need to indicate that "there is no current task". I use a combination of a NULL pointer [and then access the relevant 'reserve' data structures if the pointer is NULL] and a variable to check if a task has been created. [This is quite simplified, but the concept applies].

Technically, in MS-DOS (or other 8086 in 'real mode'), a NULL pointer would also be used to set the vector for divide by zero [which is "vector zero", and the vector table is at address zero - so NULL]. But since modern OS's have the interrupt vector table somewhere else [typically], and the address at zero is typically protected from read/write operations, that is no longer a 'valid use' of a pointer. Of course, some other embedded type systems may still use address zero for something 'meaningfull'.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
0

Off the top of my head:

  • use in strtok to get successive tokens after the first token;
  • terminate an argument list in exec* functions
  • use in realloc for initial allocation
John Bode
  • 119,563
  • 19
  • 122
  • 198
0

NULL may be safely passed to free(), so it is often useful to initialise pointers to NULL in cases where they may or may not get malloc()-ed within the following code. You can then safely call free(), e.g. at the end of the function, regardless of whether the pointer was actually used or not, e.g.

int * p = NULL; // NB: without this initialisation we would need additional logic
                //     to know whether to call free(p) or not later...
...

if (...)
{
    ...
    if (...)
    {
       ...
       p = malloc(42);
       ...
    }
    ...
}

...

free(p);         // free allocated memory, or no-op if p == NULL
Paul R
  • 208,748
  • 37
  • 389
  • 560
  • Is this behaviour of `free` guaranteed? I'm sure some implementations of C I've used in the past had very strange effects if you freed a NULL pointer. ThinkC for MacOS Classic was one... – Ken Keenan Jan 17 '13 at 22:48
  • 2
    @KenKeenan - see [Does free(ptr) where ptr is NULL corrupt memory?](http://stackoverflow.com/a/1938758/188535). The answer is: yes, it's safe. – detly Jan 17 '13 at 22:50
  • 1
    Yes, it's standard in C89 and C99 I believe, but it's possible that early implementations (pre-C89) may not have honoured this. Incidentally the same convention applies to `delete` and `delete []` in C++. – Paul R Jan 17 '13 at 22:50