Passing an Array by Reference

Passing an Array by reference in C

This is caused by the fact that arrays tend to decay into pointers.

int a[] = { 1, 2, 3 };
int* p = a; // valid: p is now the address of a[0]
a = p; // NOT valid.

printf("a = %p\n", a);
printf("p = %p\n", p); // prints same address as a

a and p will print the same value.

Contrary to what others have said, a is not a pointer, it can simply decay to one. http://c-faq.com/aryptr/aryptrequiv.html

In your first function() what gets passed is the address of the array's first element, and the function body dereferences that. Infact, the compiler is treating the function prototype as this:

void function(int* array /*you wrote int array[]*/){
array[0] = 4;
array[1] = 5;
array[2] = 6;
}

function(&array[0]);

This has to happen because you said "array of unknown size" (int array[]). The compiler could not guarantee to deduce the amount of stack required to pass by value, so it decays to a pointer.

---- Edit ----

Lets combine both your examples and use more distinctive names to make things clearer.

#include <stdio.h>

void func1(int dynArray[]) {
printf("func1: dynArray = %p, &dynArray[0] = %p, dynArray[0] = %d\n",
dynArray, &dynArray[0], dynArray[0]);
}

void func2(int* intPtr) {
printf("func2: intPtr = %p, &intPtr[0] = %p, intPtr[0] = %d\n",
intPtr, &intPtr[0], intPtr[0]);
}

void func3(int intVal) {
printf("func3: intVal = %d, &intValue = %p\n",
intVal, &intVal);
}

int main() {
int mainArray[3] = { 1, 2, 3 };
int mainInt = 10;

printf("mainArray = %p, &mainArray[0] = %p, mainArray[0] = %d\n",
mainArray, &mainArray, mainArray[0]);
func1(mainArray);
func2(mainArray);

printf("mainInt = %d, &mainInt = %p\n",
mainInt, &mainInt);
func3(mainInt);

return 0;
}

Live demo at ideone: http://ideone.com/P8C1f4

mainArray = 0xbf806ad4, &mainArray[0] = 0xbf806ad4, mainArray[0] = 1
func1: dynArray = 0xbf806ad4, &dynArray[0] = 0xbf806ad4, dynArray[0] = 1
func2: intPtr = 0xbf806ad4, &intPtr[0] = 0xbf806ad4, intPtr[0] = 1

mainInt = 10, &mainInt = 0xbf806acc
func3: intVal = 10, &intValue = 0xbf806ad0

In func1 and func2 "dynArray" and "intPtr" are local variables, but they are pointer variables into which they receive the address of "mainArray" from main.

This behavior is specific to arrays. If you were to put the array inside a struct, then you would be able to pass it by value.

C++ pass an array by reference

Arrays can only be passed by reference, actually:

void foo(double (&bar)[10])
{
}

This prevents you from doing things like:

double arr[20];
foo(arr); // won't compile

To be able to pass an arbitrary size array to foo, make it a template and capture the size of the array at compile time:

template<typename T, size_t N>
void foo(T (&bar)[N])
{
// use N here
}

You should seriously consider using std::vector, or if you have a compiler that supports c++11, std::array.

pass array by reference in golang

As others have mentioned in comments, you probably want to use a slice rather than an array. Slices are passed by reference already, so no need to specify pointers. The make statement below creates a slice of ints (backed by an array). In the code below, I gave it a length of 2 and a capacity of 100 in order to satisfy your goal of assigning to index 1.

import (
"fmt"
)

func f(a []int) {
fmt.Println(a[1])
}

func main() {
a := make([]int, 2, 100)
a[1] = 100
f(a)
}

C++ Pass a reference to an array to function

There are many different options here depending on what you want to do here.

If you have a raw array of byte objects, you can pass it into a function like this:

void hello(byte arr[]) {
// Do something with arr
}

int main() {
byte arr[4];
hello(arr);
}

The mechanism by which the array is passed into the function (a pointer to the first element of the array is passed to the function) functions similarly to pass-by-reference: any changes you make to arr in hello will stick in main even though you didn't explicitly pass in a reference to it. However, the hello function won't check whether the array has size four or not - it'll take in as input an array of any number of bytes.

You can also write

void hello(byte (&arr)[4]) {
// ...
}

int main() {
byte arr[4];
hello(arr);
}

The syntax byte (&arr)[4] means "a reference to an array of four bytes." This explicitly passes the array by reference into hello, and it will check the size of the array to make sure it's correct. However, this is very unusual syntax and rarely seen in practice.

But perhaps the best idea is to not use raw arrays and to use std::array instead:

void hello(std::array<byte, 4>& arr) {
// Do something with arr
}

int main() {
std::array<byte, 4> arr;
hello(arr);
}

Now, there's no weirdnesses about strange parentheses in the syntax for arrays of bytes and there's no worries about size checking. Everything is handled properly because std::array is an object type that has all the advantages of regular object types. I'd recommend going with this last approach above all the other ones.

Passing an array by reference in C?

In C arrays are passed as a pointer to the first element. They are the only element that is not really passed by value (the pointer is passed by value, but the array is not copied). That allows the called function to modify the contents.

void reset( int *array, int size) {
memset(array,0,size * sizeof(*array));
}
int main()
{
int array[10];
reset( array, 10 ); // sets all elements to 0
}

Now, if what you want is changing the array itself (number of elements...) you cannot do it with stack or global arrays, only with dynamically allocated memory in the heap. In that case, if you want to change the pointer you must pass a pointer to it:

void resize( int **p, int size ) {
free( *p );
*p = malloc( size * sizeof(int) );
}
int main() {
int *p = malloc( 10 * sizeof(int) );
resize( &p, 20 );
}

In the question edit you ask specifically about passing an array of structs. You have two solutions there: declare a typedef, or make explicit that you are passing an struct:

struct Coordinate {
int x;
int y;
};
void f( struct Coordinate coordinates[], int size );
typedef struct Coordinate Coordinate; // generate a type alias 'Coordinate' that is equivalent to struct Coordinate
void g( Coordinate coordinates[], int size ); // uses typedef'ed Coordinate

You can typedef the type as you declare it (and it is a common idiom in C):

typedef struct Coordinate {
int x;
int y;
} Coordinate;

Pass Array by Reference in C

Arrays are always passed by reference in C. The name of the array is pointer to the first element of it. So, you just do this :-

void function (int arr[]){
// Some Code.....
}
int main(){
// Some Code...
int name[5];
function(name);
// Some Code...
}

And that would work, you can modify the values of elements in the array and the changes would be reflected in the calling function.

Edit: You know that you have to add a semi-colon after your for loop? Otherwise the next one line will also be iterated. See -

Corrected Code
and
Output

Passing an array by reference isn't working

As has been mentioned, javascript uses pass-by-value, you can modify the objects elements/properties but not replace the object itself. slice returns a new array to the object. You will have to something like this instead.

slice does not alter the original array, but returns a new "one level
deep" copy that contains copies of the elements sliced from the
original array.

function callMeMaybe(i, board, boardCopy) {
if (board[i] == 1) {
//boardCopy = board.slice(0);
var length = board.length,
j = 0;

boardCopy.length = 0;
while (j < length) {
if (Object.prototype.hasOwnProperty.call(board, j)) {
boardCopy[j] = board[j];
}

j += 1;
}

boardCopy[i] = 0;
console.log(board);
console.log(boardCopy);
}
}


Related Topics



Leave a reply



Submit