7

I'm writing a small C program to do some number crunching, and it needs to pass around arrays between functions. The functions should accept and return pointers, right?

For example, this (I know it may not be the most efficient thing):

int* reverse(int* l, int len) {
    int* reversed = malloc(sizeof(*reversed)*len);
    int i, j;
    for (i = 0, j = len-1; i < len; i++, j--) {
        reversed[j] = l[i];
    }
    return reversed;
}

Am I using pointers right?

Javier
  • 4,552
  • 7
  • 36
  • 46
  • 1
    Your example looks fine. The broader topic of the difference between arrays and pointers has been addressed here before, such as at http://stackoverflow.com/questions/660752/pointer-vs-array-in-c-non-trivial-difference . – Matthew Flaschen Jun 28 '09 at 05:19
  • (This wouldn't qualify as an answer) The array and pointer algebra differ only in that sizeof(array_name) returns the count of array_name elements, not the size of the array in bytes. – jpinto3912 Jun 28 '09 at 08:34

5 Answers5

14

Your code snippet is correct. However, pointers and arrays in C are indeed different. Put simply "the pointer to type T" is not same as "the array of type T".

Please have a look at C Faq discussing Pointers & arrays to get a better understanding of this.

Community
  • 1
  • 1
Aditya Sehgal
  • 2,867
  • 3
  • 27
  • 37
2

A link to C-FAQ: Arrays and Pointers has been given already, but there is also a thorough explanation in C for Smarties: Arrays and Pointers. You may want to read the "Analyzing Expressions" page first.

A couple of things about your example which should be corrected:

  1. Using int instead of the correct size_t for storing object sizes.
  2. Failure to check the return value of malloc().

One way to "fix" this second problem is to let the caller decide where the output is stored (perhaps the caller does not want or need a freshly allocated array):

int *reverse(int *out, int *l, size_t len) {
   size_t i, j;
   for (i = 0, j = len - 1; i < len; ++i, --j) {
     out[j] = l[i];
   }
   return out;
 }
Mark Edgar
  • 4,707
  • 2
  • 24
  • 18
1

From a low level perspective, an array is a continuous chunk of memory that's accessed by the address of the beginning of that chunk and the offset, so from that abstraction level, it is a pointer. However, from C language perspective, an array type is different from a pointer type. Basically an array can be assigned to a pointer value but it's not the same type.

For the purpose of your function, you are doing OK.

Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
1

In pedantic theory, arrays and pointers are different things, since an array specifies a region of memory and therefore an array's size is part of its type. So one says that an array name decays to a pointer when used in that context. There's a detailed explanation in the C-FAQ.

In practice they're the same since formally a[i] is the same thing as *(a+i), and therefore the compiler back end treats an array name and a pointer in exactly the same way. The only difference worth worrying about is that

void foo()
{
   int a[5]; // allocates five words of space on the stack
   int *b;   // allocates *one* word of space on the stack (to hold the pointer)
}

Your code snippet is fine. Just be careful to free the memory that your function malloc()s in whoever calls it.

Crashworks
  • 40,496
  • 12
  • 101
  • 170
0

arrays in C are represented and manipulated by a pointer to the first element, e.g.

int arr[50];
int * ptr1 = arr;
int * ptr2 = &arr[0];

in this example, ptr1 == ptr2 because the address of the first element of the array and the base pointer for the array are the same.

so your basic example is correct, though I suspect that the malloc should probably be:

int* reversed = malloc(sizeof(int)*len);

Steven A. Lowe
  • 60,273
  • 18
  • 132
  • 202
  • That's just in case I want to change it to something else (a `long`, for example) so I won't have to change two things. – Javier Jun 28 '09 at 05:00
  • 1
    Nope, his malloc is fine (and preferable to yours) since C99. – smcameron Jun 28 '09 at 05:02
  • @[smcameron]: @reyjavikvi]: an interesting technique (I didn't notice the * prefix the first time, sorry about that!). I learned C in 1982 and haven't used it very much since 1994, so I've never read the C99 spec (must have missed the memo on that! ;-)) – Steven A. Lowe Jun 28 '09 at 05:22