Batdude
Batdude

Reputation: 556

Java Array of Objects crashes

Java noob question:

Consider the following C array and initializer code:

struct {
  int x;
  int y;
} point_t;

point_t points[1000];

Easy. This gets created and memory allocated at load time.

Now consider the similar in Java:

public class point_t
{
   public int x;
   public int y;
}

point_t points[] = new point_t[1000];
// Without this loop, java will crash when you run this
for (int i=0; i<1000; i++)
{
   points[i] = new point_t;
}
points[0].x = 10;  // Crash would occur here without above loop
points[1].x = 10;

Initially my java program was crashing with a null pointer dereference. The problem was that, coming from C++, I was not aware that you have to create the 1000 point_t objects. Just a comment but this seems INSANE. Suppose the array size was 1 million or 1 billion. It would literally take seconds simply to "create" this array with empty entries at run time. In C++ it all happens at load time. I admit that you don't always know what would be in the C++ array's cells, but in embedded systems where I work, quite often the memory is auto initialized to zeros so it works.

So is there any easier, quicker, more efficient way in Java to create an array and allocate the memory when you have an array of objects? Or am I doing something wrong in the code above?

Upvotes: 4

Views: 888

Answers (4)

Diego Lins de Freitas
Diego Lins de Freitas

Reputation: 625

You can use the Flyweight pattern to share the same data between different objects and defer the creation of the point object until it is really necessary

Upvotes: 1

duffymo
duffymo

Reputation: 308763

That's not an array of point_t instances; those live out on the heap.

It's really an array of references to those point_t instances out on the heap.

Any reference that is not initialized by being assigned to a reference value (e.g. by calling new) is set to null.

It's true for non-array reference types, too.

public class Person {
    private String name; // not initialized; that means it's null
    public Person() {} // oops; constructor should have initialized name, but now it's null
    public String getName() { return name; } // returns null unless you set it properly
    public void setName(String newName) { this.name = newName; }
}

Upvotes: 2

Marvo
Marvo

Reputation: 18143

Writing

point_t[] points = new point_t[ 1000 ];

is allocating a thousand references to point_t objects. (In C parlance, it's allocating pointers to structs of that type.)

That loop

for (int i=0; i<1000; i++)
{
    points[i] = new point_t;
}

allocates a new point_t object, and puts the references (pointer) to it in the array. Until you did that, the array was nothing but nulls, and it probably gave you null exceptions.

Upvotes: 4

Ray Toal
Ray Toal

Reputation: 88378

Since you are coming from a C++ background, this may help. In Java, when you write

point_t points[] = new point_t[1000];

This is similar to writing, in C++,

point_t* points[] = new point_t*[1000];

That is, in Java, when you create the array, you are not creating an array of point objects, but rather and array of point references, the same as if you would have created an array of point pointers in C++.

Java is a managed (garbage-collected) language; that is what Java programmers would expect.

As for the second part of your question, how one would create the objects themselves, what you did is fine. Create 1000 point objects in a loop and load them up. If you want shorter code, you can write a nice method to do this work. :)

You can also look into other collection libraries that might have these kind of convenience factory methods.

Upvotes: 7

Related Questions