2

I am having trouble finding a way to get the array size from within a function. Here is my code:

#include <stdio.h>

void printBuff(char *buf);
int main()
{
    char arr[12] = "csdlnclskjn";
    printf("Array size: %d, element size: %d. ",sizeof(arr), sizeof(arr[0]));
    printBuff(arr);
    return 0;
}

void printBuff(char *buf){
    printf("Array size: %d, element size: %d.",sizeof(buf), sizeof(buf[0]));
}

As seen above, printBuff does the same as the second line in the main function. However, the outputs are different:

Array size: 12, element size: 1. Array size: 4, element size: 1.

Thinking about it, I understand why the output is 4 in the printBuff() method. In fact, arr is a pointer to the first element of the array. On a 32-bit architecture, sizeof(arr) will then return 4, on 64-bit one it will return 8. What I do not understand is why sizeof(arr) returns the size of the array instead of the number of bytes of the pointer when used in the main() function. After all, arr, when invoked inside main(), is still a pointer, right?

So my questions are:

  1. How come sizeoff() is interpreted differently depending on the context in which it is used? What does this depend on?

  2. How to get the actual array size (number of elements in array) from within a function, without passing the size as an argument, without using methods such as iterating over the array while incrementing a counter until '\0' is reached - just the simplest way to get array size regardless of the context.

  3. Incidentally, where does the compiler/system responsible for remembering the size of the array store the size of the array? How is it associated with the array and how is it retrieved?

I wanted to iterate though an array using sizeof(buf), / sizeof(buf[0]) as the size of the array but apparently that is not possible.

bkr879
  • 2,035
  • 2
  • 15
  • 23
  • 1
    Your array decays to a pointer in the function. That is *all* that is known so you have to pass the array length too. the size of an array (in `main`) is not the same as the size of a pointer (in the function). – Weather Vane Sep 10 '16 at 19:20
  • @WeatherVane: It's not converted in the function. It's converted when the argument expression is evaluated, before the function is called. – Keith Thompson Sep 10 '16 at 19:50
  • @KeithThompson oh good grief. "At" the function then. – Weather Vane Sep 10 '16 at 19:52
  • Possible duplicate of [How to get the real and total length of char \* (char array)?](http://stackoverflow.com/questions/21022644/how-to-get-the-real-and-total-length-of-char-char-array) – Elias Van Ootegem Sep 10 '16 at 19:54
  • @WeatherVane: It's an important distinction. There's a common misconception that passing an array expression to a function is a special case. It isn't. The "conversion" happens when the array expression is evaluated (with a few stated exceptions). – Keith Thompson Sep 10 '16 at 19:59
  • @KeithThompson ok "the array has decayed to a pointer in the function". – Weather Vane Sep 10 '16 at 20:05
  • @WeatherVane: True, but why not say "the array argument decays to a pointer before it's passed to the function"? – Keith Thompson Sep 10 '16 at 20:51
  • @KeithThompson how about "the array is decaying to a pointer *at the moment* it is passed" ? Hm? How can it decay to a pointer *before* it is passed? What you say, implies that the array has become different in the calling function. Apart from this pedantic noise, do you have anything else to say about my first comment? Is it so wrong? – Weather Vane Sep 10 '16 at 22:07
  • @WeatherVane: It decays to a pointer *when it's evaluated*, which happens before the resulting value is passed. Yes, your first comment is (mildly) incorrect; the conversion doesn't happen in the function. (Strictly speaking, my interpretation is that the array-to-pointer "conversion" is really a compile-time operation, but that's another can of worms.) – Keith Thompson Sep 10 '16 at 22:36

1 Answers1

3

so here are my answers for your questions:

  1. The array is "converted" into char* type when passed into the function (with the char* parameter).
  2. AFAIK there is no such way. You could use strlen function for strings. Otherwise, you have to pass the length as parameter.
  3. See How does an array pointer store its size?

Don't use sizeof(buf)/sizeof(buf[0]) to get length of an array when passing array parameters. See this. for more information.

Community
  • 1
  • 1
  • The argument against `sizeof(buf)/sizeof(buf[0])` applies only to array *parameters* (because there's no such thing as an array parameter in C). It doesn't work because what looks like an array parameter is really a pointer parameter. `sizeof buf / sizeof buf[0]` works correctly if `buf` is an array object. – Keith Thompson Sep 10 '16 at 20:53
  • Thank you for your comment. I agree and I am editing my answer. Although, it is described in the link I have included. –  Sep 10 '16 at 21:08