-2

Watch here:

int main(void){
 int array[10];
 printf("%d",sizeof(array));
}

In this case, it shows 40, but how does sizeof work?
'array' is only an address, how does it determinate the size with only an address?

---EDIT---
I badly explained myself... I know that an array is not an address, but the word array used in this program equates to an address

AlessandroF
  • 542
  • 5
  • 16

5 Answers5

4

'array' is only an address

It is not. You believe some false things about arrays.

An array is not an address. An array may be used in a context that expects the address of an array element.

I can use orange peels in a recipe that calls for lemon peels; that does not mean that oranges are lemons.

how does it determinate the size with only an address?

It does not.

array is an array of ten four-byte integers. The compiler knows that. Your program is equivalent to printf("%zu",10 * sizeof int);.

(Pedantic note: sizeof gives the size in chars. It just so happens that the vast majority of the time, a char is one byte.)

In C99 it is legal to say:

int n = whatever();
int b[n + 10];
printf("%zu\n", sizeof b);

and sure enough this will print out (n + 10) * sizeof int.

How on earth does it do this?

Beats the heck out of me. Find the source code for a C99 compiler and see what it does. But first think: if you had to write a compiler that had that property, what would you do?

Finally, pop quiz: what does this program do?

int main(void){
 int array[10];
 int *pi = array;
 printf("%zu\n", sizeof array);
 printf("%zu\n", sizeof pi);
}
Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 1
    Nice quizz, here's another one: `char s1[] = "1234567890"; char* s2 = "1234567890";` --> different sizeof 's – A.S.H Mar 22 '17 at 23:18
  • Thank you, but i know that an array is not a pointer, but in THIS case, the word 'array' represents a pointer – AlessandroF Mar 24 '17 at 17:10
  • @AlessandroF: The sooner you stop believing those false things you believe, the sooner you will be able to reason correctly about C programs. – Eric Lippert Mar 24 '17 at 17:24
1

sizeof gives you the size of the array in chars (which are 1 byte long on most systems).

Each int is 4 chars long on your system, so to get the size in number of elements of the array, try:

sizeof(array) / sizeof(int)

Keep in mind that this will only work for arrays that are allocated statically. For arrays that are dynamically allocated (i.e. using malloc), you'll have to keep the length of the array safe elsewhere, or otherwise have some magic value at the end of the array that will let you iteratively find the size of the array (by looping through it until you get to the magic value). A common "magic value" is NULL.

Sizeof uses the typename of the symbol provided to it (or the type provided to it) in order to determine size. An int varname[10] takes sizeof(int) * 10 chars. If you were to use

int *varname = (int*)malloc(sizeof(int) * 10));

then, sizeof(varname) would give you the same result as sizeof(int *), which is (in most cases) either 4 or 8, depending on whether you are on a 32 bit or 64 bit system.

Note that when using an initializer for an array:

int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};

Then sizeof(array) will return the same value as it would were it run on:

int array[10];

This is because C would know the size of the array at compile time, and infer the type of array to be an array of 10 ints in both cases.

Anish Goyal
  • 2,799
  • 12
  • 17
  • 1
    I'm not sure about terms like "length" and "true size". They suggest legitimacy where there is none; those are not concepts with universally agreed on meaning. – Kerrek SB Mar 22 '17 at 23:17
  • You're absolutely right. I changed length to size in bytes, and true size to length in number of elements. – Anish Goyal Mar 22 '17 at 23:18
  • 1
    Much better, thanks! – Kerrek SB Mar 22 '17 at 23:19
  • 1
    sizeof is **not a function**. It is a (unary) operator. – wildplasser Mar 22 '17 at 23:29
  • My mistake - I removed that word from the answer. – Anish Goyal Mar 22 '17 at 23:31
  • 3
    And while we're being pedantic, sizeof in C gives you the size in *chars*, not *bytes*. It just happens that on most systems, chars are one byte. If chars were two bytes and ints were four bytes, then sizeof int would be 2. (In C# by contrast, sizeof is defined in terms of bytes, and chars are two bytes.) – Eric Lippert Mar 22 '17 at 23:34
  • Updated that as well, I was not aware of that. I checked the docs, thank you for pointing that out. – Anish Goyal Mar 22 '17 at 23:39
  • 1
    The vast majority of C implementations use bytes for chars, so it is a really pedantic note. Most compiler docs just say bytes. :-) – Eric Lippert Mar 22 '17 at 23:49
1

Arrays are a distinct type. They convert to pointers to their first element inside of arithmetic expressions and in function calls, however a sizeof expression is neither.

sizeof is an operator (sizeof array (without the parens) works too) and that operator gets access to the real type of the variable, which is int[10] ( whose size is sizeof(int) * 10 ).

By the way, the type of the value of a sizeof is size_t so you need to print it with %zu, not %d.

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
0

When the compiler produces an executable, it determines the size and puts that directly into the code to be run. Note that sizeof(int) on different platforms can be different).

The run-time executable code ends up working like this:

#define SIZEOF_INT (4)
#define SIZEOF_ARRAY (4*SIZEOF_INT)
int main(void){
 int array[10];
 printf("%d",SIZEOF_ARRAY /*compiler replaces sizeof(array) here */);
}

'array' is still an address at run-time (within the executable). But sizeof(array) gets changed to a number equivalent to the size at run-time.

B. Wolf
  • 682
  • 6
  • 12
0

Please check this link that contains the explanation you're looking for and this will help you solve your issue. by Mark Harrison.

How do I determine the size of my array in C?

To determine the number of elements in the array, we can divide the total size of the array by the size of the array element. You could do this with the type, like this:

int a[17];
int n = sizeof(a) / sizeof(int);
and get the proper answer (68 / 4 = 17), but if the type of a changed you would have a nasty bug if you forgot to change the sizeof(int) as well.

So the preferred divisor is sizeof(a[0]), the size of the zeroeth element of the array.

int a[17];
int n = sizeof(a) / sizeof(a[0]);
Community
  • 1
  • 1
handiansom
  • 783
  • 11
  • 27