freonix
freonix

Reputation: 1625

Passing address of array as a function parameter

Recently, I was debugging one of my programs and found a mistake that I've constantly make, but it was not shown as a warning during compilation, so I've just assume everything was in place and was OK. I a bit confused on what's happening in the code below:

void foo(char b[2]);
char a[2] = {1, 2};
foo(a);   // I always assumed that this would pass the entire array to be
          // duplicate in stack, guess I was wrong all this while
          // Instead the address of the array was passed

void foo(char b[2])
{
   // Value of b[0], b[1]?
   // Does this mean :   1) b[0] == &a[0]?
   //                or  2) b[0] == &a[0+2]?
   // Compiler didn't complain, so I assume this is a valid syntax
}

Upvotes: 4

Views: 8785

Answers (6)

gui pn
gui pn

Reputation: 662

I should make a correction: the address of the array is not passed - it's the address of the array's first element. The simplest way of putting it is:

In C, the value of an array is a pointer to its first element.

If you work with arrays of arrays, you need to supply information about the sizes of arrays after the first dereference:

// either the following or: void foo(char param[][30][20])
void foo(char (*param)[30][20])
{
    // ...
}


int main(void)
{
    // bar is an array of 10 arrays of 30 arrays of 20 chars.
    // its value's TYPE is 'pointer to an array of 30 arrays of 20 chars,
    // which is what foo above requires.
    char bar[10][30][20];

    foo(bar);

}

Upvotes: 0

lccarrasco
lccarrasco

Reputation: 2051

When you pass an array as a parameter to a function it decays into a pointer, this is defined in the C standard in 6.7.1:

On entry to the function the value of each argument expression shall be converted to the type of its corresponding parameter, as if by assignment to the parameter. Array expressions and function designators as arguments are converted to pointers before the call. A declaration of a parameter as “array of type” shall be adjusted to “pointer to type,

This essentially means that in your function declaration it's equivalent to use

void foo(char b[2]); or void foo(char b[]); or void foo(char *b)

`

Upvotes: 7

Dair
Dair

Reputation: 16240

b[0] = &a[0] if you do foo(a) as the argument.

If you pass foo((a+1)) then b[0] = &a[1] (you shouldn't do that though since b[1] would be undefined) and so on.

Upvotes: 0

ephemient
ephemient

Reputation: 204926

  1. When you declare an array as a function parameter, it is treated as if it were a pointer. Your foo is completely identical to

    void foo(char *b)
    {
        ...
    }
    
  2. Arrays decay to pointers. In other words, in some uses (e.g. sizeof(a)) a is an array, but in others where a pointer is expected, the name a means the address of a[0].

Upvotes: 0

Dietrich Epp
Dietrich Epp

Reputation: 213648

This is the same as the following:

// The array "char b[2]" "decays" to a pointer "char *b"
void foo(char *b)
{
    // b[0] == a[0]
    // also, b == a (two addresses, both the same)
}

You can read up on how arrays and pointers in C behave very similarly (but not exactly the same). Arrays decay to pointers if they're function arguments (but not anywhere else). The real gotcha here is that on a 64-bit system, sizeof(b) == 8 and sizeof(a) == 2, which is somewhat surprising unless you know about arrays decaying into pointers.

Upvotes: 0

alex
alex

Reputation: 490481

It is valid syntax, and yes, when passing an array the memory address of the first element is copied, but when you dereference the address, you are modifying the original array.

Upvotes: 0

Related Questions