1

To demonstrate, here is an example code recreating the instance of passing a dynamically allocated array to a function.

#include <stdio.h>
#include <stdlib.h>
void fx1(int* arr) {/* code here */ }
int main() {
    int *arr = (int *) malloc(sizeof(int) * 10);
    fx1(arr);
    free(arr);
    return 0;
}

In the example, I first create a dynamically allocated array, arr. Then, I pass it to a function called fx1. The title is exactly my question. Is passing a dynamically allocated array to a function in C an instance of pass-by-value or pass-by-reference? I would also like a reference/s (book, documentation, etc) if you have an answer for this.

Mercado
  • 606
  • 6
  • 20

2 Answers2

1

It is "both":

The pointer is passed by value, the array "by reference".

C Standard draft, N1256:

6.5.2.2 Function calls
...
4 An argument may be an expression of any object type. In preparing for the call to a function, the arguments are evaluated, and each parameter is assigned the value of the corresponding argument.
...

I put "both" and "by reference" in quotes, because there are no references in C. A pointer is not a reference, but when used to "pass an array" to a function, it is roughly comparable, in the sense that if the function modifies the array, the changes are visible to the caller. I think this helps understanding what happens here.
We say that an array decays to a pointer, when passed to a function. "Decay" because the pointer looses some information, namely the length of the array. So saying this is similar to "pass by reference" is meant only from an application point of view.

alain
  • 11,939
  • 2
  • 31
  • 51
  • Explanation, or source? – Mercado Oct 19 '15 at 10:37
  • That explains why a pointer is passed by value since the pointer in the function call is another local variable that is different from the one in main. Am I right? – Mercado Oct 19 '15 at 10:53
  • Yes, exactly. The pointer in the function is a copy, but it points to the same array. – alain Oct 19 '15 at 10:56
  • Thanks. What is the reason that the array is passed by reference? – Mercado Oct 19 '15 at 10:59
  • Strictly speaking, everything is passed by value in C. So you pass a pointer by value. But a pointer is a bit like a reference, so you could say you pass an array "by reference". In C, there is no way to pass an array by value, it's impossible. – alain Oct 19 '15 at 11:03
  • C does not have pass by reference, so no, it it not "both". The function gets the **value** of the pointer. Anything else is at a higher abstraction layer beyond the C semantics. – too honest for this site Oct 19 '15 at 11:04
  • @Olaf, yes, I know, that's why "both" is in quotes. – alain Oct 19 '15 at 11:06
  • And do not cite long outdated standard drafts. (although I admit **this** has not changes significantly) Here is the final draft for the current standard: http://port70.net/~nsz/c/c11/n1570.html – too honest for this site Oct 19 '15 at 11:11
  • Yes, @Olaf, I understand what you mean. But I think viewing a pointer as similar to a reference helps to understand what happens. I updated my answer. – alain Oct 19 '15 at 11:24
  • The question is about C, not higher abstration semantics. And there is a clear difference between pointer an reference: the pointer has a value on its own (the address it points to), the reference's value is the object it points to. As C does not enforce this (like e.g. C++), it is solely a convention beyond the language itself. – too honest for this site Oct 19 '15 at 11:30
  • @Olaf, you really don't have to tell me the differences between a reference and a pointer. I wrote *similar*, not *equal*. This is a "beginner" question, so I think it really doesn't help to be too nit-picky. It's about understanding, so higher abstractions are relevant, IMO. – alain Oct 19 '15 at 11:39
  • Especially for a beginner question it **is** relevant to be exact to get the concepts right! Once he has understood, terms can be relaxed a bit. But the latter not on SO, because this will be read by other beginners. So being precise is vital here. – too honest for this site Oct 19 '15 at 11:45
  • I withdrew the DV, but you should just might want to add that "reference" is a pure application view and not enforced by the C language/implementation or environment. – too honest for this site Oct 19 '15 at 11:48
1

In C, everything is passed by value. In your concrete example arr is. You don't have references like in C++ or Java.

Let's take a C++ example:

void foo(int& i) {
    ++i;
}

int main() {
    int i = 1;

    foo();
}

Here, true references are used. i is passed by reference and foo modifies i over a reference to i. No "copying by value" takes place.

OTOH, in C, you don't have references. You can only write something like

void foo(int* i) {
    ++*i;
}

int main() {
    int i = 1;

    foo(&i);
}

To pass something "by reference"1 in C, you need to pass a pointer to it, just like you did. The pointer itsself is passed by value but it refers to a memory area (here i) modifiable by both the function and the allocator.

In the end, if you want to pass something "by reference" in C, copying by value is always involved. Not so in C++.

Quoting from K&R, 1.8 Arguments - Call by Value:

In C, all function arguments are passed by value.''


1 Note that this is within double quotes. C doesn't have "pass-by-reference." Period.

cadaniluk
  • 15,027
  • 2
  • 39
  • 67
  • "In C, everything is passed by value." "To pass something "by reference" in C, you need to pass a pointer to it." The two seem contradictory. Can you explain a little bit more from a C perspective? – Mercado Oct 19 '15 at 10:33
  • @Mercado To resolve the contradictory part I put double quotes around "by reference." Technically, there is no such thing in C. Anyway, you can pass a pointer to some memory location to a function to let the function modify it. – cadaniluk Oct 19 '15 at 10:34
  • Okay. Any basis/source for this information, especially for "In C, everything is passed by value."? – Mercado Oct 19 '15 at 10:36
  • I don't think I passed a pointer to "it". You can change the contents of the array, but on the contrary, if you change the value of "it" (arr) inside the function call, by giving it a new memory address using malloc, the new memory address will not occur from where you invoked the function call (which is main function) because arr is a local variable in the function. Correct me if I am wrong, I want to understand what it really means to say "pass-by-reference", it seems to be confusing when it comes to arrays. – Mercado Oct 19 '15 at 10:49
  • @Mercado: For most usages (IIRC all but `&`, `_Alignof`, `sizeof`), an array **decays** to a pointer. – too honest for this site Oct 19 '15 at 11:06
  • @Mercado - You also don't pass an array to the function, you pass a pointer (by value). If you want to update the pointer, you pass a pointer to the pointer(!). That's all you have in C. If you want to call that pass-by-reference or not, is up to you. – Bo Persson Oct 19 '15 at 11:06
  • 1
    I see it that way: References are at a higher abstraction than C provides. So any "reference" is a matter of application semantics, not C. – too honest for this site Oct 19 '15 at 11:08
  • I am familiar with the & symbol in the function parameters in C++. Like this: void fnx1(int &a) Is this what is considered as pass-by-reference? – Mercado Oct 19 '15 at 11:22
  • @Mercado Yes, this is a true reference. – cadaniluk Oct 19 '15 at 11:24
  • @cad, there's an error in the second code block: `++i` would increment the pointer, not the value. And shouldn't the footnote read "C doesn't have "pass by reference""? – alain Oct 19 '15 at 14:50
  • @alain Two in one... that's fairly bad. Thanks anyway. – cadaniluk Oct 19 '15 at 14:51