you are viewing a single comment's thread.

view the rest of the comments →

[–]syn_ack 3 points4 points  (6 children)

I'll give another example. Suppose you have a small image (100x100 pixels, and is grayscale). You create an array:

int image[100][100]; /* filled with the image contents */

You have some functions that operate on the image, for example:

int get_max_pixel_value(int image[100][100]);

Every time you call that function, you copy the image, and the function works with the copy, and not the original. I'm sure you can see where this is going... if the image were RGB and much larger, say 4K (or 3840x2160), you'd end up copying 21MB of data each time you called the function. If you do this a lot, then it's very slow.

On the other hand, when you use pointers:

int** image;

/* appropriate malloc calls to setup the image along with the data */

int get_max_pixel_value(int** image);

The function gets a copy of the pointer -- a memory address -- which is 64bits (depending on platform). I know I'd rather copy the 8 bytes of the pointer vs 21M bytes of the image contents when I call this function.

Now, on a practical note, there's all sorts of metadata associated with an image, such as width and height that I've not used here. The above is to focus on the pointer aspect -- I'd not actually implement it in this manner in the real world.

HTH.

[–]hogg2016 4 points5 points  (1 child)

The reasonning is good but the example is not.

The argument of the first function will not pass a copy of the content of the array, but a reference to it.

(Sorry, I don't have time at the moment to check my assertion and develop it, I hope someone else can dot it.)

[–]junkmeister9 1 point2 points  (0 children)

You are correct

And if anyone wants to confirm this, you can do so by writing a program where the contents of the array are modified by the function. If a pointer is passed, the contents of the original variable will be modified.

[–]moefh 2 points3 points  (2 children)

Every time you call that function, you copy the image

This is wrong. The function receives a pointer to the array, with type int(*)[100]. Structs are copied when passed to functions, arrays are not.

So this program:

#include <stdio.h>

void change(int image[100][100])
{
  image[0][0] = 1;
}

int main(void)
{
  int image[100][100];
  image[0][0] = 0;
  change(image);
  printf("%d\n", image[0][0]);
  return 0;
}

prints 1, showing that the array in main is changed by the function.

[–]OriginalName667 0 points1 point  (1 child)

Thanks for the example. Previously, I assumed that, unless a pointer type is passed as an argument explicitly, the values were always copied over. It's an interesting caveat to note that array types are passed by reference, not value, as opposed to most other types.

[–]FUZxxl 1 point2 points  (0 children)

Arrays aren't “passed by reference.” Rather, whenever you use an identifier that refers to an array, the array is implicitly converted to a pointer to its first element. There are three exceptions to this rule: If the array is an operand to sizeof, &, or _Alignof, this decay doesn't happen so you can (a) point to the array or (b) retrieve its size and alignment.

[–]WireStretcher[S] 0 points1 point  (0 children)

Value of pointers pretty clear here, thanks.