5

I was browsing for finding a way to find number of rows and columns in of a given matrix without any additional information and I came around this answer.

Given a matrix, find number of rows and columns

This is the code snippet from the second answer of the question above :

int main()
{
    float a[9][2]={{0,1},{1,1}};
    int row=(sizeof(a)/sizeof(a[0]));
    int col=(sizeof(a)/sizeof(a[0][0]))/row;
    printf("%d\n",row);
    printf("%d\n",col);
    return 0;
}

How does the sizeof(a[0]) turns out to be 8? In my understanding the pointers have a generic size of 4 bytes in 32 bit arch and 8 bytes in 64 bit arch. I printed out the sizeof(a[0]) on both the machines and the answer is still 8. Anybody has any clue why?

Edited : I mean to say doesn't a[0] decay into a pointer?

Community
  • 1
  • 1
Dark Innocence
  • 1,389
  • 9
  • 17
  • 6
    Because `a[0]` is one row of the matrix, which contains 2 floats, each size 4 bytes. – Weather Vane Aug 26 '16 at 11:31
  • 18
    *"In my understanding the pointers..."* -- There are no pointers in the code you posted. – axiac Aug 26 '16 at 11:31
  • 3
    `a[0]` is an array. Arrays and pointers are different. The array has 2 elements each of size 4, so the total size is 8. – M.M Aug 26 '16 at 11:32
  • 7
    Arrays aren't pointers and pointers aren't arrays. – Baum mit Augen Aug 26 '16 at 11:32
  • 1
    There are many answers here. Why don't you post one? :) – Harald Aug 26 '16 at 11:38
  • But a[0] is an address right ? When I dereference it I get 0, it means a[0] holds the address of 0, indirectly saying a[0] is a pointer – Dark Innocence Aug 26 '16 at 11:39
  • 2
    Just because an array decays into a pointer in almost all places does not mean it is one. It is just part of the way the language works. – NathanOliver Aug 26 '16 at 11:40
  • `a[0]` decays to a pointer. But a[0] is not a pointer. The biggest difference occurs when you try to `sizeof` it. – Rishikesh Raje Aug 26 '16 at 11:40
  • This is a "tail wags dog" question. The rows are 9 and the columns are 2, as shown in the definition. I don't understand why you want "a way to find number of rows and columns in a given matrix without any additional information" when you only just defined those arrays yourself, using that information. If you had used `#define` or a `const` that information would be there ready to use in subsequent code. – Weather Vane Aug 26 '16 at 11:47
  • 1
    About *"finding a way to find number of rows and columns in of a given matrix"*: Note that arrays themselves do not store their size for run time. It is only available at compile time, and only if you have the actual array object available (and not, for example, decayed pointer to array). – hyde Aug 26 '16 at 11:50
  • If an array decayed to a pointer when passed to `sizeof`, how would you find out the size of an array? – molbdnilo Aug 26 '16 at 11:53
  • @WeatherVane the problem statement doesn't specify the M x N dimensions for me. – Dark Innocence Aug 26 '16 at 11:58
  • @DarkInnocence you *cannot create* a 2-D array without specifying the row length. – Weather Vane Aug 26 '16 at 12:01
  • @WeatherVane I'm given a matrix of M x N. I have to find its rows(M) & columns(N). – Dark Innocence Aug 26 '16 at 12:05
  • As said, you can't, if a function is "given a matrix". You either have to be passed its dimensions, or the data can contain unique end markers. But that is not what the question asked. – Weather Vane Aug 26 '16 at 12:09

4 Answers4

11

There are no pointers used anywhere in the code posted. Arrays do not decay to a pointer-to-first-element when passed as operand to sizeof (1).

  • a is a 2D array, of type float [9][2].
  • a[0] is the first item in this 2D array, which is a 1D array of type float [2].
  • sizeof(a) gives the size of the 2D array, equivalent to sizeof(float) * 9 * 2.
  • sizeof(a[0]) gives the size of the 1D array, equivalent to sizeof(float) * 2.
  • float is apparently 4 bytes on your system, 4 * 2 = 8.

(1) See the specification of the sizeof operator in ISO 9899:2011 6.5.3.4:

When applied to an operand that has array type, the result is the total number of bytes in the array.

The rule of "array decay" is found in 6.3.2.1/3:

Except when it is the operand of the sizeof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue.

Lundin
  • 195,001
  • 40
  • 254
  • 396
5

But a[0] is an address right ?

No, a[0] is a 1 Dimensional array. It decays to a pointer in almost all cases. However in the case of a sizeof operation, you will get different answers for both.

As a[0] is a 1D array of 2 floats, sizeof(a[0]) gives 8.

Rishikesh Raje
  • 8,556
  • 2
  • 16
  • 31
3

a[0] is an array of 2 floats (float[2]). Hence, sizeof(a[0]) is equivalent to sizeof(float[2]) in your code. On your platform sizeof(float) is 4 and hence sizeof(a[0]) is 8.

But the size of float is irrelevant forthe purpose of calculating the row and column as you do. The code you have is always going to give correct row and column values irrespective of sizeof(float).

P.P
  • 117,907
  • 20
  • 175
  • 238
1

a is a two dimensional array. The first dimension is the number of total arrays you have and the second number is the the number of element in each array. So float a[9][2] means you have 9 arrays all right next to each other(arrays are contiguous) and each array has two elements.

Now if we look at the sizeof operator we see that it is defined as

When applied to an array, the result is the total number of bytes in the array. This implies that the size of an array of n elements is n times the size of an element.

for arrays.

So now that we know that sizeof gives the total size of the array if given an array and we know that a[n] represents on of the two element arrays in a then sizeof(a[0]) is the total size of one of the first array(and all of them since the array is not jagged) which happens to be 8 since sizeof(float) is 4.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • You should be careful when quoting the C++ standard in C discussions. The full text from the C standard goes: `The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.` Now, you wouldn't find that in C++ since the C has VLAs and therefore the `sizeof` operator behaves differently. – Lundin Aug 26 '16 at 11:55
  • The quoted part in this answer is true for C too though, just be careful with all the dirty details that make C and C++ different. – Lundin Aug 26 '16 at 11:57
  • 1
    @Lundin I didn't even see the C tag on the Q. I only saw the C++ tag. Still the relevant part is all that matters here. – NathanOliver Aug 26 '16 at 11:58