Throw a null-pointer exception

14

3

Your task is to generate a null-pointer exception. That is, your program must accept a value which it expects to be non-null, and throw an exception/error or crash because the value is null.

Furthermore, it can't be obvious from reading the code that the value is null. Your goal is to make it seem clear to the reader that the value is not null, even though it actually is.

  • Instead of null, you can use nil, none, nothing, or whatever the equivalent is in your language. You can also use undefined, uninitialized, and so on.
  • The problem with your code must be that the variable is (surprisingly) null where the program expects a non-null variable.
  • Your program can respond to the null by throwing an exception, throwing an error, crashing, or whatever it normally does when an unexpected null is encountered.

This is a popularity contest, so be clever!

Ypnypn

Posted 2014-05-16T00:24:19.277

Reputation: 10 485

Question was closed 2016-11-19T20:57:49.833

I'm closing this question because underhanded contests are off topic per community consensus.

– Dennis – 2016-11-19T20:57:49.833

@Ourous Can you give an example to show what you mean? – Ypnypn – 2014-05-16T02:23:58.913

After looking over it, It's more of a cast error than what you're looking for. – Οurous – 2014-05-17T00:12:23.040

Am I allowed to use a compiler bug? – Mark – 2014-05-17T08:32:27.823

1@Mark It is a popularity contest; let the community decide. I'd definitely vote for a compiler bug. – 11684 – 2014-05-17T09:01:31.637

Answers

33

Java

Let's calculate the absolute value of a number. Java has Math.abs for this purpose, however the number we're using could be null sometimes. So we need a helper method to deal with that case:

public class NPE {
    public static Integer abs(final Integer x) {
        return x == null ? x : Math.abs(x);
    }

    public static void main(final String... args) {
        System.out.println(abs(null));
    }
}

If x is null, return null, else use Math.abs().
The code is very simple and clear, and should work fine... right?

By the way, using this line instead:

return x == null ? null : Math.abs(x);

works correctly. I thought about making this a spoiler, but.. I think it's just as puzzling :)

Ok, an explanation:

First, Math.abs does not take an Integer, but an int (there are also overloaded methods for other numeric types) and also returns an int. In java, int is a primitive type (and can not be null) and Integer is its corresponding class (and can be null). Since java version 5, a conversion between int and Integer is performed automatically when needed. So Math.abs can take x, automatically converted to int, and return an int.

Now the weird part: when the ternary operator (?:) has to deal with 2 expressions where one has a primitive type and the other one has its corresponding class (such as int and Integer), one would expect that java would convert the primitive to the class (aka "boxing"), especially when the type it needs (here for returning from the method) is the reference (class) type, and the first expression is also of the reference type. But java does exactly the opposite: it converts the reference type to the primitive type (aka "unboxing"). So in our case, it would try to convert x to int, but int can not be null, thus it throws a NPE.

If you compile this code using Eclipse, you will actually get a warning: "Null pointer access: This expression of type Integer is null but requires auto-unboxing"

Also see:
https://stackoverflow.com/questions/7811608/java-npe-in-ternary-operator-with-autoboxing
https://stackoverflow.com/questions/12763983/nullpointerexception-through-auto-boxing-behavior-of-java-ternary-operator

aditsu quit because SE is EVIL

Posted 2014-05-16T00:24:19.277

Reputation: 22 326

Hint: http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.25

– James_pic – 2014-05-16T14:19:32.557

SPOILERS What happens when x != null? (I figured it out already.) – 11684 – 2014-05-17T09:03:13.080

@11684 when x is not null, it works fine – aditsu quit because SE is EVIL – 2014-05-17T09:31:55.650

Then I think I do not know how this works. If it works when x is not null and I'm right about why this throws, the colon has to be parsed in two senses (which I would not put in a Language Specification). – 11684 – 2014-05-17T09:38:30.967

@11684 not sure what you mean about "two senses", but anyway I added an explanation now – aditsu quit because SE is EVIL – 2014-05-17T10:27:42.077

Yes, there's two different cases in which you will need a colon. One is the one displayed here. It's used to separate the bodies of a ternary operator. The second one is in foreach loops. – IchBinKeinBaum – 2014-05-17T11:18:01.180

@IchBinKeinBaum I know that; I'm sorry it's so vague what I meant. My initial idea was that the colon was used as a division operator (auto-unboxing could allow this), but that would corrupt the ternary expression (there would be no expression for the false case). To handle the case x != null (and work like I thought it did) the colon should have been parsed as a division operator (sense one) and as delimiter (separating the last two expressions). – 11684 – 2014-05-17T12:07:59.127

This (and related issues) is one of the main reasons considering ' ? : ' to be just a fancy 'if-else' is a bad idea – Richard Tingle – 2014-05-17T12:42:20.377

@11684 I'm not aware of any programming language that uses ":" for division. Java definitely doesn't. – aditsu quit because SE is EVIL – 2014-05-17T12:50:42.637

@aditsu Ha, how stupid. I'm even in the top 30% for the Stackoverflow tag. I'll go home now :'(. – 11684 – 2014-05-17T12:52:27.573

This is absolutely dastardly. +1. – Maxpm – 2014-05-18T06:20:20.767

23

C

Every C programmer made this error, at least once.

#include <stdio.h>

int main(void) {
    int n=0;
    printf("Type a number : ");
    scanf("%d",n);
    printf("Next number is : %d",n+1);
    return 0;
}

Reason :

scanf takes a pointer (int *) in argument, here 0 is passed (NULL-pointer)

Fix:

scanf("%d",&n);

http://ideone.com/MbQhMM

Michael M.

Posted 2014-05-16T00:24:19.277

Reputation: 12 173

1It's not exactly like that. scanf is a variadic function, and argument of incorrect type (int) was given, when it expected int *. Because C (I know, compilers can detect this in case of scanf) cannot check the types in variadic function, this happily compiles. 0 is indeed null pointer literal, but this only applies to the directly used literal itself, without storing it in a variable. n never contained a null pointer. – Konrad Borowski – 2014-05-17T18:34:22.823

You also need to check the return value of scanf to fix this function. – David Grayson – 2014-05-18T06:07:14.233

1@David It's not correct without checking the return value, but it won't crash or invoke UB - n will remain at 0. (To see this happen, try redirecting an empty file as stdin.) – Riking – 2014-05-18T11:07:30.433

14

PHP

This one has bitten me a few times.

<?php

class Foo {
  private $bar;

  function init() {
    $this->bar = new Bar();
  }

  function foo() {
    $this->bar->display_greeting(); // Line 11
  }
}

class Bar {
  function display_greeting() {
    echo "Hello, World!";
  }
}

$foo_instance = new Foo();
$foo_instance->init();
$foo_instance->foo();

Expected result:

Hello, World!

Actual result:

Fatal error: Call to a member function display_greeting() on a non-object on line 11

a.k.a. NullPointerException

Reason:

By default, constructor syntax is backwards compatible with PHP 4.x, and as such, the function foo is a valid constructor for the class Foo, and thus overrides the default empty constructor. This sort of error can be avoided by adding a namespace to your project.

primo

Posted 2014-05-16T00:24:19.277

Reputation: 30 891

9

CoffeeScript (on Node.js)

In CoffeeScript, ? is existential operator. If the variable exists, it's used, otherwise right hand side is being used. We all know that it's hard to write portable programs. Case in point, printing in JavaScript is under specified. Browsers use alert (or document.write), SpiderMonkey shell uses print, and Node.js uses console.log. This is crazy, but the CoffeeScript helps with this issue.

# Portable printer of "Hello, world!" for CoffeeScript

printingFunction = alert ? print ? console.log
printingFunction "Hello, world!"

Let's run this under Node.js. After all, we want to make sure our script works.

ReferenceError: print is not defined
  at Object.<anonymous> (printer.coffee:3:1)
  at Object.<anonymous> (printer.coffee:3:1)
  at Module._compile (module.js:456:26)

Uhm, why would you complain about that, when alert is also not defined?

For some reason, in CoffeeScript, ? is left associative, which means it ignores undefined variables only for the left side. It's unfixed, because apparently some developers may depend on ? being left associative.

Konrad Borowski

Posted 2014-05-16T00:24:19.277

Reputation: 11 185

8

Ruby

Find awk in the PATH of a Unix clone.

p = ENV['PATH'].split ':'

# Find an executable in PATH.
def find_exec(name)
  p.find {|d| File.executable? File.join(d, name)}
end

printf "%s is %s\n", 'awk', find_exec('awk')

Oops!

$ ruby21 find-awk.rb
find-awk.rb:5:in `find_exec': undefined method `find' for nil:NilClass (NoMethodError)
        from find-awk.rb:8:in `<main>'

From the error, we know that p.find called nil.find, so p must be nil. How did this happen?

In Ruby, def has its own scope for local variables, and never takes local variables from the outer scope. Thus the assignment p = ENV['PATH'].split ':' is not in scope.

An undefined variable usually causes NameError, but p is a special case. Ruby has a global method named p. So p.find { ... } becomes a method call, like p().find { ... }. When p has no arguments, it returns nil. (Code golfers use p as a shortcut for nil.) Then nil.find { ... } raises NoMethodError.

I fix it by rewriting the program in Python.

import os
import os.path

p = os.environ['PATH'].split(':')

def find_exec(name):
    """Find an executable in PATH."""
    for d in p:
        if os.access(os.path.join(d, name), os.X_OK,
                     effective_ids=True):
            return d
    return None

print("%s is %s" % ('awk', find_exec('awk')))

It works!

$ python3.3 find-awk.py 
awk is /usr/bin

I probably want it to print awk is /usr/bin/awk, but that is a different bug.

kernigh

Posted 2014-05-16T00:24:19.277

Reputation: 2 615

7

C#

With() is an extension method to the string object, which is essentially just an alias for string.Format().

using System;

namespace CodeGolf
{
    internal static class Program
    {
        private static void Main()
        {
            Console.WriteLine( "Hello, {0}!".With( "World" ) );
        }

        private static string With( this string format, params object[] args )
        {
            Type str = Type.GetType( "System.string" );
            MethodInfo fmt = str.GetMethod( "Format", new[] { typeof( string ), typeof( object[] ) } );

            return fmt.Invoke( null, new object[] { format, args } ) as string;
        }
    }
}

Looks good, right? Wrong.

Type.GetType() requires a fully-qualified, case-sensitive type name. The problem is that System.string doesn't exist; string is just an alias for the actual type: System.String. It looks like it should work, but str.GetMethod() will throw the exception because str == null.

Most people who know a bit about the internal specifics of the language will probably be able to spot the problem fairly quickly, but it's still something that's easily missed at a glance.

Tony Ellis

Posted 2014-05-16T00:24:19.277

Reputation: 1 706

That is a great one :D – Knerd – 2014-05-16T14:57:57.350

This is a little too obvious. The reader get an immediate clue because there are two ways to do the same thing .GetType() and typeof() and thus leading to a fault when the result is not the same. I think the poster wanted bullet proof looking code which isn't. – ja72 – 2014-05-18T14:42:00.990

Why would reflection be used in this extension method? The obvious code is return string.Format(format, args);. If reflection was needed (in another use case), one would use typeof(string) (catches casing mistakes at compile-time, no magic string), not the static GetType method. So the example seems "unrealistic". – Jeppe Stig Nielsen – 2014-06-02T12:46:48.043

4

Unity3D

public GameObject asset;

Then you forget to drag&drop the asset there and BOOM, Unity explodes. Happens all the time.

Fabricio

Posted 2014-05-16T00:24:19.277

Reputation: 1 605

3wait, development in unity3d requires a mouse? – Einacio – 2014-05-16T15:19:28.793

1@Einacio if you want things easier you can just dragNdrop an asset to a variable. Very handy. But you can code without that if you want to. – Fabricio – 2014-05-16T15:40:17.533

4

Ruby

Just some simple code to take the product of an array.

number_array = [2,3,9,17,8,11,14]
product = 1
for i in 0..number_array.length do
  product *= number_array[i]
end
puts product

Two things here. One is that the .. range operator is inclusive. So 0..x has x+1 elements and includes x. This means that the we exceed the bounds of the array. The other thing is that when you do this in Ruby, it just gives you a nil back. This is a lot of fun when, say, your program throws an except ten lines after the bug.

Hovercouch

Posted 2014-05-16T00:24:19.277

Reputation: 659

This is kindof too obvious. It's like doing for (int i = 0; i <= arr.length; i++) in Java. – Cole Johnson – 2014-05-18T21:17:23.780

3

Android

I see this happen too often. A person passes a message to the next activity (maybe a status code, map data, whatever), and ends up pulling a null from the Intent.

At first glance it seems pretty reasonable. Just:

  • make sure the message isn't null
  • pack it into the intent
  • start new activity
  • get intent in new activity
  • extract message by tag

In MenuActivity.java:

private void startNextActivity(String message){
    // don't pass a null!
    if(message == null)                        
        message = "not null";        

    // put message in bundle with tag "message"
    Bundle msgBundle = new Bundle();
    msgBundle.putString("message", message);   

    // pack it into a new intent
    Intent intent = new Intent(this, NextActivity.class);
    intent.putExtras(msgBundle);               
    startActivity(intent);
}

In NextActivity.java:

private void handleMessage(){
    // get Intent
    Intent received = getIntent();
    if(received == null){
        Log.d("myAppTag","no intent? how does this even happen?");
        finish();
    }
    // get String with tag "message" we added in other activity
    String message = received.getStringExtra("message");
    if(message.length() > 10){
        Log.d("myAppTag", "my message is too long! abort!");
        finish();
    }
    // handle message here, etc
    // ...
    // too bad we never GET here!
}

FWIW, the JavaDoc does say that Intent.getStringExtra(String) may return null, but only if the tag wasn't found. Clearly I'm using the same tag, so it must be something else...

Geobits

Posted 2014-05-16T00:24:19.277

Reputation: 19 061

2The problem with this answer is that people not familiar with Android development (such as me) won't be able to appreciate it. – John Dvorak – 2014-05-16T05:00:27.040

@JanDvorak Agreed, but no big deal. There are other answers on the site that I don't fully appreciate also. :) – Geobits – 2014-05-16T12:52:22.150

3

C

Just a quick read from the buffer, where the programmer has even been kind enough to document the potential danger!

char* buffer;
int main( void )
{
    ///!!WARNING: User name MUST NOT exceed 1024 characters!!\\\
    buffer = (char*) malloc( 1024 );
    printf("Please Input Your Name:");
    scanf("%s", buffer);
}

Very simple and obvious trick if you're expecting malicious code. The comment ending '\' escapes the newline, so the buffer is never allocated memory. It will then fail the scanf, as buffer will be NULL (as file scope variables are zero initialised in C).

Bilkokuya

Posted 2014-05-16T00:24:19.277

Reputation: 241

0

Nimrod

type TProc = proc (a, b: int): int

proc func1(a, b: int): int=a+b
proc func2(a, b: int): int=a-b

proc make_func(arg: int, target: var TProc)=
  if arg == 1:
    target = func1
  elif arg == 2:
    target = func2
  else:
    raise newException(EIO, "abc")

var f, f2: TProc

try:
  make_func(2, f)
  make_func(3, f2)
except EIO:
  discard

echo f(1, 2)
echo f2(3, 4)

What's happening here is a little complicated. In Nimrod, procedures are default initialized to nil. In the first make_func call, it succeeds. The second, however, throws an exception and leaves f2 uninitialized. It is then called, causing an error.

kirbyfan64sos

Posted 2014-05-16T00:24:19.277

Reputation: 8 730

0

C#

This is classical. The very useful method FindStringRepresentationOf will create a new instance of the specified type parameter, then find the string representation of that instance.

Surely it will be wasteful to check for null immediately after having created a new instance, so I haven't done that...

static void Main()
{
  FindStringRepresentationOf<DateTime>();  // OK, "01/01/0001 00:00:00" or similar
  FindStringRepresentationOf<DateTime?>(); // Bang!
}

static string FindStringRepresentationOf<TNewable>() where TNewable : new()
{
  object goodInstance = new TNewable();
  return goodInstance.ToString();
}

Changing object in the local variable declaration into TNewable or into var (C# 3 and later) makes the problem go away. Hint: Boxing of Nullable<T> (a.k.a. T?) is anomalous in the .NET Framework.

After having fixed the issue as described in the invisible text above, aslo try goodInstance.GetType() (the difference being that GetType(), unlike ToString(), is non-virtual, so they could not override it in the type Nullable<>).

Jeppe Stig Nielsen

Posted 2014-05-16T00:24:19.277

Reputation: 602

0

C++:

#include <iostream>
#include <cstring>
#include <vector>
#include <conio.h>
#include <string>

using namespace std;

class A
{
public:
    string string1;
    A()
    {
        string1 = "Hello World!";
    }
};
A *a_ptr;

void init()
{
    A a1;
    a_ptr = &a1;
}

int main()
{
    init();
    cout<<a_ptr->string1;
    _getch();
    return 0;
}

What you would expect is "Hello World!" to be printed. But you will see only garbage on the screen.

Here the a1 is destroyed when the scope init() is finished. So a_ptr, as it points to a1, will produce garbage.

wadf

Posted 2014-05-16T00:24:19.277

Reputation: 161

0

C

#define ONE 0 + 1

int main(void) {
    printf("1 / 1 = %d\n", 1 / ONE);
    return 0;
}

Explanation

The preprocessor doesn't actually calculate 0 + 1, so ONE is literally defined as 0 + 1, resulting in 1 / 0 + 1, which is a division by zero, and results in a floating point exception.

nyuszika7h

Posted 2014-05-16T00:24:19.277

Reputation: 1 624