tags:

views:

362

answers:

5

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?

+1  A: 

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
your bold statement begs explanation.
Steven A. Lowe
nevermind, Crashworks explained it already
Steven A. Lowe
A: 
Steven A. Lowe
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 Badia
Nope, his malloc is fine (and preferable to yours) since C99.
smcameron
@[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
+13  A: 

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.

Aditya Sehgal
Upvoted for C Faq - more detailed than an answer you would get on SO.
Tyler McHenry
+1 for the C FAQ
Robert
A: 

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
A: 

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