1

So I have this array in a header file like this:

// header.h
static const unsigned int array1[]={0x00,0x01,0x02,0x03};

And:

// file.c
main()
{
     unsigned int *ptrToArray;

     ptrArray = &array1[0];
 }

Correct me if I am wrong. I assume: to find the number of bytes of array elements, instead of sizeof(array1) the equivalent will be sizeof(*ptrArray), right?

And to access the elements of the array, instead of array[i], it will now be:

  • *(ptrArray) for the first element,
  • *(ptrArray+1) for the 2nd element so on right?
pb2q
  • 58,613
  • 19
  • 146
  • 147
user1357576
  • 389
  • 2
  • 3
  • 17
  • Why don't you just compile and try it yourself? Those are all very easy things to verify. In the amount of time it took you to write the question, you could have already had it compiled and be playing with it. – Jonathon Reinhart Jul 17 '12 at 18:16
  • If you are only interested in the number of elements in `array1`, you can use `sizeof (array1) / sizeof (int)`. That seems more relevant to copying an array than the rest of this discussion. – bkconrad Jul 17 '12 at 18:39
  • possible duplicate of [How to find the sizeof(a pointer pointing to an array)](http://stackoverflow.com/questions/492384/how-to-find-the-sizeofa-pointer-pointing-to-an-array) – Bo Persson Jul 17 '12 at 18:51

4 Answers4

4

The type of *ptrToArray is int, therefore sizeof(*ptrToArray) is the same as sizeof(int). So it won't tell you anything about the number of elements in array1.

Whilst you can write *(ptrArray+1), etc., you should just write ptrToArray[1]!

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • So I understood the sizeof concept now better. Thanks. But I am also wondering, what is the equivalent of sizeof(array1) now? Is there no way to do it without copying the entire array into a temporary location? – user1357576 Jul 17 '12 at 18:31
  • @user1357576: There is no equivalent. You will have to track the size of the array manually. – Oliver Charlesworth Jul 17 '12 at 18:32
2

A pointer is not an array, and an array is not a pointer. An array can decay into a pointer when convenient, but it is still a complete type.

So, the type of *someIntPointer is int, not an array, even if that pointer happens to point to the first element in an array. sizeof(someArray) works as you would expect because it knows that the type is actually an array.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
0

sizeof won't behave in the same way for your pointer: your example will give you the size of the datatype: unsigned int.

And while you can use pointer arithmetic to reference elements through ptrArray, you can just as well use standard array dereferencing: ptrArray[0], ptrArrray[1], ... and in most cases you're better off doing so.

pb2q
  • 58,613
  • 19
  • 146
  • 147
-2

Sizeof will return the size of the pointer for regular pointer types. If you sizeof a dereferenced pointer type, you will get the size of the element (i.e. sizeof(unsigned int)). You will need to either keep track of the number of elements in the array yourself, or use sizeof on the array declaration.

As for accessing, you could do it that way, but you can just use the bracket notation as you would with a normal array.

Arrays are a special class of pointer. The compiler knows when to treat an array as an array and when to treat it as a pointer: that's how it knows how big an array is, but you can still pass it to functions that expect an array (when you do this, you get a pointer to the first element). The same does not work in reverse however: The compiler will never treat a pointer declared as a pointer as an array.

By the way, [] just simplifies to pointer arithmetic. You can add a pointer to an int, but you can also add an int to a pointer. You can thus (but probably shouldn't) do weird things like 1[ptrArray]

Wug
  • 12,956
  • 4
  • 34
  • 54
  • Obligatory -1 for "arrays are a special class of pointer". That final paragraph is somewhat misleading. – Oliver Charlesworth Jul 17 '12 at 18:18
  • Same here. Arrays are certainly not a "special class of pointer", they are a completely separate type, which can *decay* into a pointer when needed. – Ed S. Jul 17 '12 at 18:21
  • Do tell me then. What are they? And if they're not a special class of pointer, why does the compiler cast between then implicitly? Why are they treated exactly the same? Conceptually, your array declaration is nothing more than a pointer to the base address. As far as goes anything I've ever read, the only programmatic difference between an array and a pointer is that with an array, the compiler knows exactly how big the pointed to contents are, and with a pointer, it assumes there is only one. – Wug Jul 17 '12 at 18:21
  • @Wug: The compiler doesn't cast between them implicitly, at least not always. If it did, then the following would be valid: `int x[10][20]; int **p = x;`. – Oliver Charlesworth Jul 17 '12 at 18:23
  • Yet, the following is: `void foo(int a[], int len); foo(someptr, 6);` – Wug Jul 17 '12 at 18:25
  • 1
    @Wug: Yes, you've declared a function that takes a pointer (not an array), and `somearray` has *decayed* into a pointer to its first element. Conversely, the following does not compile: `void foo(int **a); int x[10][20]; foo(x);`. – Oliver Charlesworth Jul 17 '12 at 18:26
  • There is a good treatment of the subtle differences in section 5.7 of the K&R book. – bkconrad Jul 17 '12 at 18:29
  • In my opinion, if it walks like a duck, quacks like a duck, decays into a duck when used in most ways, and can fly backwards, that's a reasonable argument for being called a special class of duck. I just use this description because it's easy to write and easy to understand (and more or less correct, despite the fact that everyone hates it). I'm not sure why people get so worked up about it. – Wug Jul 17 '12 at 18:33
  • C99? isn't that the one where the following is a compiler error: `for (int i = 0; i < 10; ++i);`? Seems a bit ..... dated. – Wug Jul 17 '12 at 18:36
  • @Wug: [No](http://ideone.com/npCrB). Is there a newer C standard you'd like us to be using? – Oliver Charlesworth Jul 17 '12 at 18:38
  • I guess C99 is the exception to that rule. Though I could swear that I had a project I wrote to C99 standards and it refused to accept inline declarations in for loops. I can't dig it up now though. However, if you select the "C" option (it uses the same version of the same compiler without requiring C99 strict compliance) it will compile fine – Wug Jul 17 '12 at 18:43
  • @Wug: That's an ideone.com thing. The "C" option compiles without warning flags enabled. The "C99" option compiles in C99 mode, and with warning flags enabled. – Oliver Charlesworth Jul 17 '12 at 18:44
  • @Wug: Ok, but it's precisely this issue that leads to the endless SO questions about passing 2D arrays to functions, or how confusion about jagged arrays, or when to malloc with multidimensional arrays, etc. etc. – Oliver Charlesworth Jul 17 '12 at 18:46
  • I find it's easier to explain it this way and then build incrementally on their knowledge later than it is to dump the whole thing on them at once. Especially because newbies don't generally wind up trying to solve problems with jagged multidimensional arrays. If you're using jagged ones, at that point you've pretty much evolved past the extra functionality of arrays and are using purely malloc'd pointers anyway. It's probably best practice to stop using static arrays and use malloc'd ones ASAP, since a big array declared on the stack will smash it and blow up for seemingly no reason. – Wug Jul 17 '12 at 18:50