0

In C, when we pass an array in a function call, only a pointer to the array is passed to aid memory and time efficiency, and we cannot calculate the size of the array in the called function. We have to pass the size as a parameter to the called function. However, in Java, we can calculate the size of the array in the called function too. So, doesn't it affect memory efficiency as I suppose the whole array is being passed to the called function. Could someone please elaborate on this?

user3126841
  • 155
  • 2
  • 2
  • 9

5 Answers5

2

The array in java is an object, that contain the elements and the size of the array.

When you pass an array, only the reference to the array object is passed - the array is NOT duplicated, and any change made to the array in the method will be reflected to the calling environment.

amit
  • 175,853
  • 27
  • 231
  • 333
  • okay..so the array object has a member element that represents its size? – user3126841 Aug 26 '14 at 17:45
  • @user3126841 `yourArray.length`. The `length` field represents the size of the array. – bcsb1001 Aug 26 '14 at 17:46
  • 1
    @user3126841 Just think of an Array as a type of Object, with a 'public final int length' and 'length' other members that are addressed indirectly through a [] operator. Other than that, they follow the same basic ideas that apply to other Objects. Although Java bytecode doesn't say an Array object has a 'length' member and is instead accessed by the 'arraylength' opcode. – Smith_61 Aug 26 '14 at 17:47
  • Thanks a lot everyone..I got it now :-) – user3126841 Aug 26 '14 at 17:50
2

Java and C are completely different languages, and they treat arrays very differently; don't assume the rules for one apply to the other.

In Java, arrays are subclasses of the Object class, and inherit all the attributes and methods of that class. Java arrays set aside a contiguous block of memory for the array elements (at least, I think it's contiguous), but they also set aside memory for array metadata and the base Object methods.

In C, arrays are simply contiguous sequences of elements of type T with no additional metadata.

C was derived from an earlier language known as B; in B, when you declared an N-element array, the compiler would set aside N+1 "cells", one of which would store an offset to the beginning of the array, and that cell would be bound to the identifer; given the declaration

auto arr[2];

you'd see something like this in memory:

        +---+        
   arr: |   |-----+
        +---+     |
         ...      |
        +---+     |
arr[0]: |   |<----+
        +---+
arr[1]: |   |
        +---+

Ritchie initially kept this separate pointer variable, but ran into problems when he added struct types to the language. Eventually, he got rid of it altogether, so when you declare an array, what you get is simply:

        +---+     
arr[0]: |   |
        +---+
arr[1]: |   |
        +---+

There's no separate storage for the pointer to the first element; instead, the pointer is computed when you use the array name in an expression (that is, unless it's the operand of the unary & or sizeof operators, arr will evaluate to the address of the first element of the array, or &arr[0])1.

In both Java and C, the only thing that gets passed to a function is a reference (Java) or pointer (C) to the array, not a copy of the array itself.


1. Because there's no separate pointer variable, both arr and &arr will give you the same value (the address of the first element of the array is the same as the address of the array), but the types of the two expressions will be different; the first will be T * and the second will be T (*)[N]. Note that in B, &arr would give you a different result from arr.
John Bode
  • 119,563
  • 19
  • 122
  • 198
0

Arrays are passed by value, where the value is a memory address of the array.

Also, read my detailed response here State of an ArrayList in a recursive method

Community
  • 1
  • 1
Gary Drocella
  • 337
  • 1
  • 2
  • 11
  • 2
    You could argue everything is passed by value in Java. Since Object's are just pointers, their value is copied to the called function or copied on return. – Smith_61 Aug 26 '14 at 17:43
  • you can't argue that because the jvm does not copy a 4K object onto the stack, it will copy a 4byte memory reference for objects. – Gary Drocella Aug 26 '14 at 17:45
  • 2
    Yes you can. Objects in java are pointers that point to a location in memory. These are passed by value. When you declare 'Object obj' in java. You are not declaring an Object you are declaring a pointer or reference to a memory location. Hint the NullPointerException you get when accessing null objects. – Smith_61 Aug 26 '14 at 17:50
  • @Smith_61 Read my detailed response here http://stackoverflow.com/questions/25109793/state-of-an-arraylist-in-a-recursive-method/25109872#25109872 – Gary Drocella Aug 26 '14 at 17:55
  • 1
    I don't see how that is any different to what I said. Java Object variables are just pointers/references to the actual Object, and those pointers/references are copied by value. – Smith_61 Aug 26 '14 at 18:00
  • But they are not pointers in the classic C sense. You are not able to change the reference of the parameter being passed into the method as you would be able to do in C as long as you do not declare const int* x; In java, it is only the value of the memory address, and therefore it is not possible to change the reference itself. – Gary Drocella Aug 26 '14 at 18:04
  • 1
    They are pointers in the C sense. You are confusing them with pointers to pointers. When you declare 'Object obj' in Java, you are basically declaring 'Object *obj' in C. You are not declaring 'Object **obj' where you can edit the pointer in a called function. There is a big difference. – Smith_61 Aug 26 '14 at 18:08
  • @Smith_61 No, You have not read and understood my detailed response. There is a disconnect in your understanding of pointers in C/C++ and Passing object memory references by value. Perhaps this will clear things up for you http://www.javaworld.com/article/2077424/learn-java/does-java-pass-by-reference-or-pass-by-value.html – Gary Drocella Aug 26 '14 at 18:12
  • 1
    Everything you are pointing me to, is saying the exact same thing I am saying. Object references are passed by value because they are just pointers. http://pastebin.com/LBe5iSt2 and it's equivalent C++ code http://pastebin.com/iX17uCtS – Smith_61 Aug 26 '14 at 18:19
  • I never said anything about pointers to pointers in java. They could be emulated with a generic Pointer class that stores a pointer to an object or another pointer – Smith_61 Aug 26 '14 at 18:52
  • This could never happen in Java, Here is a paste bin http://pastebin.com/S6dVUHXR – Gary Drocella Aug 26 '14 at 18:53
  • You could do that in java. Read my previous comment on a generic pointer class. If you used just those, you would effectively be using pointers to pointers – Smith_61 Aug 26 '14 at 19:10
  • @Smith_61 The thing is that the built in constructs of the java language, that is, when passing parameters to a methods, **Everything** is pass-by-value. Emulation is not a built in java construct. – Gary Drocella Aug 26 '14 at 19:45
  • Again, I don't see where what you are advocating is any different than what I am saying. Since the start I have been saying that everything is passed by value, including variables of an Object type. – Smith_61 Aug 26 '14 at 20:53
0

The difference here is that arrays in Java are objects that know their own sizes. We're still passing a reference to the array, it's just that the memory being referred to has the information that's not carried in C.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
0

in Java (almost)everything is a pointer (more specifically a reference), as opposed to C where everything is a value.

a small example to illustrate:

in C:

struct MyStruct {
    int  myInt;
    bool myBool;
};
MyStruct a = { .myInt = 5, .myBool = true};
//following line will cause a CLONE of a to be put in b.
MyStruct b = a;

the above code declares a struct, initializes it and clones that struct to another struct(meaning values are copied not references i.e. changing one will not change the other).

in java stating b = a is copying the reference only (i.e. changing a.myInt will also change b.myInt), to achieve something similar in C we would write have b be a pointer to MyStruct and state b = &a

Therefore, when passing arguments to methods in java we are actually passing the reference to that object (unless we are using primitive types e.g. int, bool, char, etc). Java arrays come conveniently prepacked with their size (in C we could just make a struct of an array and an int as it's length).

Assaf
  • 1,352
  • 10
  • 19