So I just discovered that Java allows us to create arrays of size 0. Does that mean that the array is both empty and full at the same time? I figured this out while working on an array based implementation of a priority queue. Would it be right to say that it is empty and full at the same time when calling methods checking for this? Or should I not allow the creation of an array of size 0? Thanks.
Java arrays have no definition of full or of empty. Consider
int[] foo = {0};
int[] bar = new int[1];
Is foo full because it has a value assigned to its only position?
Is bar empty because it has no values assigned?
Both arrays are the same, they both have one value stored and in both cases the contain the value 0.
Full implies you can't add any more items, you can never add new items to java arrays, just replace existing items, so either all arrays are full or full does not make sense for a java array. I say it is the second.
for example: why this statement long[] n= new long[]; is wrong but this statement
long[][] n= new long[1][]; is right? How does the memory know how much memory needs to be assigned to the object in the second statement?
How does the memory know how much memory needs to be assigned to the object in the second statement?
Two things to remember here to figure out what's going on:
2D Java arrays aren't square, they're arrays of arrays.
You specify the size of an array when it's created.
So in this example, you're creating an array of longs (of size 1) to hold another array of longs - but you're not yet creating the second array (so you don't need to specify how large it will be.) In effect, the first array provides an empty "slot" (or slots if the outer array is longer than 1) for the inner array(s) to sit in - but the inner array(s) haven't yet been created, so their size doesn't need to be specified.
It doesn't just create an array of arbitrary length at all, it simply doesn't create any inner arrays.
You can perhaps see this more clearly if you try to access or store a long in the 2D array:
long[][] x = new long[2][];
x[0][0] = 7;
...will produce a NullPointerException (on the second line), because there is no inner array there to access.
In the first example that doesn't compile, you're trying to actually create an array of longs, but not giving it a dimension, hence the error.
when you write this - long[][] n= new long[1][];
you are creating array of arrays of long but you are not actually initializing those arrays right now
So if you do n[0] == null it will return true
that way you are free to initialize new array in any point of time later-
n[0] = new long[10];
So the point is - you need to provide size while initializing your array , that is why long[] n= new long[]; is wrong
How to create an array that extends itself. I don't want to use the classes like ArrayList and Vector etc to do this. Instead i need to generate an array that extends it's size upon adding elements to it. This is question by my teacher.
Say for example, i want an int[] which extends it's size.
For instance, the user want to enter the student IDs into an array. The array has no fixed size since there are no fixed no. of students in this case. When the user says he wants one more, the array's size should be incremented by one.
Any answer is appreciated.
Arrays are fixed in length, you can not increase or decrease the size of array.
What you can do create new array with larger size and copy the values using Arrays#copyOf source array to new destination array.
Note: Arrays#copyOf internally call System.copy which does shallow copy.
Here is a useful link for your teacher, from the docs:
An array is a container object that holds a fixed number of values
of a single type. The length of an array is established when the array
is created. After creation, its length is fixed.
The only option to do that without ArrayList/Vector.. is creating a new array and copying the values to it.
Your description, 'When the user says he wants one more, the array's size should be incremented by one.' is just a pointer array, which is LinkedList in java.
Whatever your teacher says there is no way to resize a array dynamically without creating a new array with edited size. I don't think any language supports this requirement. Just create a new array and copy the existing one.
I think i'll have to re-initialize the array with an incremented size but before that, i think i'll have to copy all those elements into a temporary array and then again copy them into the original array whose size is changed.
If this is correct, my teacher might be looking for this. But that degrades the performance though.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
If I have a pointer in C++, let's say int* array;, I allocate memory for the array with
array=new int[10];
Then, I initialize all 10 elements of the array, with 0,1,2,3...
After that, I do array=new int[15];
will the initial first 10 values still be there? I assume not, correct me if I'm wrong.
In C there is the function realloc, which has the effect described above. Is there any equivalent in C++ or java?
How can I dynamically expand an array (without using Vector class, and without copying the array each time in another array with double capacity) in C++ or Java?
Whenever you do new int[X] where X is an integer, in both C++ and Java, you obtain a reference to a newly allocated array.
In Java, arrays are automatically initialized so that each entry has its default value (0 for primitive data types, null for reference data types). In C++, the array is not initialized, you get garbage on it.
If you do:
array = new int[10];
array[0] = 0;
array[1] = 1;
// etc
array = new int[15];
the second time you create an array and put a reference to it in the variable array, you simply lose the reference to your first array. Since it is a new array, it will obey the language's rules for newly allocate arrays: in Java, array will now point to an array of size 15 filled with zeroes; in C++, array will point to an array of size 15 filled with garbage.
In Java, the lost array will be eventually garbage collected for you. In C++, you've just created a memory leak.
Both languages forbid you to resize or, as you put, dynamically expand an array. You can create a new one, copy everything from the old one to the new one, and discard the old one. They might provide methods that make these operations for you, but you won't expand the existing array, you will simply create a new one and copy the data from the old one to the new one.
In Java there's no realloc (but it has Arrays.copyOf, which works similarly), and in C++ (and C as well), realloc won't really extend the array; it will allocate more memory elsewhere, deallocate the memory previously allocated, and return the new pointer: you'd have to replace any existing pointers to the new address!
Finally, for collection classes that dynamically resize themselves, they usually have an internal array and, whenever that array gets full, the class does all that resizing internally: it allocates a new one, bigger, copies the elements, and discards the old one. Since the array is completely encapsulated in the class, you don't need to worry about references to the old array as I explained above.
In java memory management is under control of JVM. That is the beautity of java. You can use System.arraycopy() function to make a copy of an array. If your aim is to expand array just give a bigger array as destination array.
On the other hand you can use collections framework for dynamically expanding collections.
The heart of array concept, both in C++ and Java, is fixed size collection. realloc may look like some kind of backdoor in this conception, but it still doesn't promise to expand given array - it may create array in other location, copy original content and release original memory. And quite probably it will.
So, if you want variable size collection, use std::vector in C++ and ArrayList in Java. Or you can code this functionality by yourself. But I'm afraid you will have to start with own memory allocator, as you cannot make standard one expand once allocated chunk of memory.
will the initial first 10 values still be there?
In C++, there will be somewhere, but you have lost your handle to them. They will be inaccessible. This constitures a memory leak.
int* array=new int[10]; // array points to dynamically allocated array
array=new int[15]; // array points to a completely different place now
In the example above, the array pointer is the only handle you have on the first dynamically allocated array. By making it point elsewhere, you leak the array.
Note also that in C++ the elements of the array are not zero initialized. In order to do that, you need to value initialize the array:
int* array=new int[10]();
// ^^
In Java you cannot dynamically extend an array. There are different data structures for that like ArrayList.
In Java, in your example if no reference is left to the first array with size 10, it will be collected by GarbageCollector.
How can I dynamically expand an array (without using Vector class, and without copying the array each time in another array with double capacity) in Java?
In java.util.Arrays, there are a lot of method to use. In your situation you need copyOf
Api Docs
array = Arrays.copyOf(array, 15);
In C++ new always returns a pointer.
The name of arrays is a pointer to the first element in the array so here is what would happen.
int *array; //get a point of type int
array=new int[10]; //allocate 10 ints, and set the array ponter to the first one
array = new int[15] //allocate 15 ints, and set the array pointer to the first one
the problem is now we have no way of knowing where in memory the first 10 ints are. The operating systems "thinks" we are using it b/c we asked for it. but we cann't use it b/c we don't know where it is.
now for something helpful. Use vectors, vectors are objects in c++ that have dynamic memory allocation built into them, so you don't have to manually do it your self.
If you really want to see how it is done, you can make object that handle memory allocation your self.
The best option in C++ is stl and std::vector<int> I have no idea why you can't use it but lets say, that you can't. Probably the best way:
const int c_startSize = 10;
const int c_increasing = 13; //1.3
int * array;
int arraySize = c_startSize;
array = new int[arraySize];
//some code
//now we need to increase size of array.
int * tmp;
tmp = new int[arraySize * c_increasing / 10];
for (int i = 0; i < arraySize; i++)
tmp[i] = array[i];
arraySize = arraySize * c_increasing / 10;
delete [] array;
array = tmp;
//some code
It is probably the only way. Of course you can use realloc or memcpy to copy values, but it is based on void pointers and for beginners usually it is more tricky. Hopefully this helped, don't forget to make a class or a struct for this thing, otherwise, it will be to much of mess.
EDIT:
Forgot to mention, my answer includes C++ only, no JAVA.
Yes, there is an equivalent in C++, which is Standard C++.
std::vector<int> array(10);
And then
array.resize(15);
The vector manages its storage memory exactly the way you expect. The vector has been designed to replace C's reallocated array pointers. To replace on-stack arrays, you have std::array since C++11. To replace on-stack VLAs, you will have std::dynarray in C++14 or C++17.
And don't get lured, realloc occasionally copies its data. (When it does not find enough space in-place to get your reallocated buffer)
About the equivalent of realloc for C++, no, there is no renew corresponding to new the way there is a realloc corresponding to malloc. And it is not something missing in the language. It has been addressed with the std::vector class. It manages its memory itself, it is efficient, and no, it is not unpure style to use it. It is the standard way in C++ to have an array that can resize.
I am studying for the OCA Programmer I Oracle Certification and hence I am reviewing all the tricky things tht might be on the exam.
One is this one:
int [] zero = new int[0];
Such an array declared as having 0 in the constructor what is going to actually do in the heap? creating a reference to what?
I have already tried to see whether it gives null or not and it does not. (zero != null) passes the test.
Do you have any idea? Thanks in advance.
Zero length array is still an array, and memory will be allocated to this array.
Array implements Object. Object is a class with methods a fields.
Size is also additional field in memory that indicates the size of array.
Additional info for tracing the reference to the object by the garbage collection is also needed.
As a result memory allocation is needed for all of this.
More interesting question when this array can be usefull, read this stackoverflow question.
what is going to actually do in the heap?
A zero-length int array.
creating a reference to what?
A reference to the zero-length int array.
I have already tried to see whether it gives null or not and it does not
Why should it?
Arrays in Java are objects. For instance it has "length" variable. and also the related data. Therefore even if you create a 0 size array only the data part will be zero in size. The other parts of the array object will be still there.