tags:

views:

181

answers:

11
?? fun()
{
   int a[3]={3,3,4};
   return &a; 
}

what could be the compatible return type. Here the pointer is pointing to the array of 3 integers not just the pointer which points to integer array. Aim is to return a pointer to array of 3 integers.

+14  A: 

First, you really should not return the address of a local variable. When the function exits, the array a will get destroyed.

As for your question, the type of &a is int (*)[].

Alexandre C.
I think with a little more explanation (of *why* OP should not return address local variable and what will happen if they try), it *would* answer the question.
FrustratedWithFormsDesigner
you're right, but OP should really really consider this. I follow your advice nonetheless and edit my answer.
Alexandre C.
+1  A: 

Don't make the mistake. As soon as fun() loses scope, so does all it's local variables.

Mark H
+1  A: 

The address of a local variable cannot be returned from a function. Local variables are placed in the stack

shk
+3  A: 

The type would be int**

But your code is wrong because your table is on the stack. Returning the pointer of an element in the stack make the reference pointing in nowhere when returning from the function.

mathk
The type would decay to int**, but it's originally a pointer to an array of 3 integers.
Victor Nicollet
The type cannot be `int**`; while an _array_ may decay to a pointer, a _pointer to an array_ may not.
James McNellis
The type would be pointer to an array of 10 integer.http://c-faq.com/aryptr/aryvsadr.html
Nyan
mathk
James McNellis
mathk
There isn't any bounds checking, no. However, if a function takes a pointer to an array of three elements, you have to call that function with an array of three elements (i.e., you can't call it with an array of two elements without some bizarre and ugly cast expression). So, you can get some safety there. As a downside, you also can't pass a pointer to the first element to such a function, so you can't use a dynamically allocated array either. There are probably other uses. To be honest, the only time I've ever used pointers to arrays is in answers to questions like this one :-).
James McNellis
A: 

If you want to return a pointer to an array, don't return the address of local variables. What you are returning here would be int**. What you want to do is allocate a new array of int, and return int*. What you want is probably something like:

int* fun()
{
    int* a = malloc(sizeof(int) * 3);
    a[0] = 3;
    a[1] = 3;
    a[2] = 4;
    return a;
}

You then need to make sure to free the allocated array later.

arsenm
+5  A: 

Don't do this.

You are returning a pointer to a local variable. When the function returns, that pointer points to a location that's no longer valid, so this exercise is pointless. The return type would have been int (*)[3] though, but when you use that as a return type of a function, the prototype would be int (*fun(void))[3] (ugh, eew)

However

If a was static, you could do

int (*fun(void))[3]
{ 
   static int a[3]={3,3,4}; 
   return &a;
}

It's more common to return a pointer to the first element in an array - though you'll have to "know" in the caller that you can access 3 and only 3 elements of that pointer.

int *fun(void)
{ 
   static int a[3]={3,3,4}; 
   return &a[0]; // or just return a;
}

Since a is static in these cases, you'll have to worry about reentrancy

2 more common ways of achieving the same:

Pass in the array through the parameters and allocate it in the caller:

void fun(int *a)
{ 
       a[0] = 3;
       a[1] = 3;
       a[2] = 4;

}

Call it like:

int a[3];
fun(a);

Dynamically allocate the memory:

int *fun(void) 
{
  int *a = malloc(3*sizeof *a);
  if(a) {
     a[0] = 3;
     a[1] = 3;
     a[2] = 4;
   }
   return a;
}

Call it like:

int *a;
a = fun();
if(a) {
  ///use a
  free(a); // remember to free it when done
} else {
  //out of memory
}
nos
Does the standard actually guarantee that returning a pointer to a locally scoped static variable will be okay? I mean, I know how it works, so I can't imagine how it would blow up.
detly
@detly: There is no problem with this except reentrancy.
Alexandre C.
A: 

Your function would have a return type of int * and you would call it like this:

int *array=fun();
printf("%d\n",array[0]); //print the first value in the array

Although! Keep in mind that this function is returning a reference to a locally created variable. There is no guarantee that the value in memory will be the same between inside and after the function call. You probably want to do something more like this:

int *more_fun(){
  int *a=malloc(sizeof(int)*3);
  a[0]=3;
  a[1]=3;
  a[2]=4;
  return a;
}

Call it like:

int *array=more_fun();
printf("%d\n",array[0]); //print the first value in the array

But when you're done, make sure to free(array) so you don't leak any memory.

sigint
+4  A: 

The return type would not be an int* or int** as others have suggested. The return type would be a pointer to an array. For example:

// we'll use a typedef so we can keep our sanity:
typedef int(*int3arrayptr)[3];

int3arrayptr fun()
{
    int a[3]={3,3,4};
    return &a; 
}

While you can return a pointer to a local variable, you cannot use such a pointer after the function returns, so you cannot use the return value of fun().

James McNellis
Unless I'm mistaken, you can't do anything with the returned pointer (not even increment or decrement it). :)
Victor Nicollet
@Victor: You are right; I said "use" in the second part of that sentence but "dereference" in the first. I've replaced "dereference" with "use" to clarify it. Thank you.
James McNellis
+1  A: 

a is a local variable. Don't return a pointer to it.

Back to the point. This is how you define a pointer-to-array-of-size-3 type in C:

int a[3] = { 1, 2, 3 };

typedef int (*p_arr_3)[3];   

p_arr_3 fun() { return &a; }
Victor Nicollet
A: 

If you were to return a, the return type would be int *. I'm not entirely sure what &a means in this case, and my handy reference tells me that the only operation that can be applied to an array is sizeof, and I don't have the Standard handy. It may be flagged as illegal, or it may just return the value of a. The only thing a denotes is the array, and the only thing like a pointer to an array is a pointer to its first element. There is no address of the address.

In C, it's hard to pass around an array, since arrays decay to pointers on the slightest provocation. If you need to pass around an actual array, it's easiest to embed it in a struct. A struct containing int a[3]; can be passed around as a regular value.

I assume that you were just giving an example, because you're returning a reference to a local variable leads to all sorts of bad things. In most implementations, that memory will be used for other things with the next function call, which means that changing a value will stomp on who-knows-what, and referencing one will get who-knows-what.

David Thornley
A: 
John Bode