0
long fibonacci(int ceiling)
{
  int counter;
  long num1 = 1, num2 = 1, sum;
  int arr[ceiling+1];
  for (counter = 1; counter < ceiling; counter++)
    {
      arr[counter] = num1;
      //printf("%d\n", num1); //prints sequence
      sum = num1+num2;
      num1 = num2;
      num2 = sum;
    }
  return arr;
}

Right now, if I try to access this array, say with int a = fibonacci(10);, it goes without a complaint. However, if I try to access an individual element, such as a[1], it tells me that

subscripted value is neither array nor pointer

What am I doing wrong?

1
  • Turn on compiler warnings and inspect all messages. Commented Apr 21, 2011 at 7:03

7 Answers 7

4

.. if i try to access an indivicual element, like a[1], or something ..

int a = fibonacci(10);

a is an integer variable and not array to use operator [] on it.

The method definition should be -

int* fibonacci(int ceiling)
{
    // ...
    return arr ;
}

int *a = fibonacci(10) ;

Now you can use [] operator on a. How ever, what you are returning is a reference of a local variable ( i.e., residing on stack ) which is wrong. You should dynamically allocate memory for the array using malloc and should later free it.

Sign up to request clarification or add additional context in comments.

2 Comments

how would I access the array?
@tekknolagi - You can just use [] on the pointer variable mentioning the index of the variable you wish to access.
2

You cannot return an array, as such, from a function in C (or C++).

What your code currently does is: it implicitly decays the int[] array to an int* pointer, and then implicitly casts the int* to a long, and then returns the long. This is not a pointer or an array, and thus the subscript operator may not be applied to it.

You could return an int*, but returning a pointer to the local arr array would be wrong (your compiler might not be able to catch the error, but you will invoke undefined behaviour at runtime) because as soon as the function finishes, arr officially does not exist and the returned pointer is therefore dangling.

You can:

  • allocate an array with malloc() and return the pointer (but then you have to figure out who is going to free() the allocation, and make sure that happens exactly once); or

  • pass in a pointer to an array, and populate the array via that pointer (now the caller is responsible for creating and managing the array) - this is probably the usual approach in C; or

  • create a struct that wraps an array, and return one of those (or, for that matter, pass in a pointer to one).

Also note that int arr[ceiling + 1]; is a C99 construct; it is not allowed in standard "traditional" C (C89 etc.), nor in standards-compliant C++. In those languages, the size of arrays must be known at compile-time.

In C++ you could also pass an array by reference, or use boost::array (which is "a struct that wraps an array", but also uses operator overloading to make it behave more transparently like an array).

1 Comment

+1 this. I'm gonna go and delete my answer right away, because, well. It is so wrong in comparison ;)
1

The easiest way to resolve this is to allocate the array at the call site and pass it to the fibonacci function to be populated.

void fibonacci(int n, int arr[])

Comments

0

You should return a int[], not a long

EDIT: Sorry, mixed C# :)

int* fibonacci(int ceiling)
....

// calling

int *a = fibonacci (10);
int val = a[20];

3 Comments

@tekknolagi - Sorry, I was using C#. Edited answer
i now get a segfault...what the heck
@tekknolagi - See Mahesh response... Too many time without using C for me, sorry. He's right regarding the memory allocation.
0

More importantly than what has been said, you should think about memory allocation. Using just int arr[ceiling+1]; will create memory for a variable with the scope within this function. You may therefore return a pointer to an array in a memory location, that could be overwritten. Use malloc instead

Comments

0

A better version with bugs fixed :

#include <stdio.h>
int fibonacci(int ceiling, int *arr)
{
  int counter;
  long num1 = 1, num2 = 1, sum;
  if(arr == NULL)
      return -1;
  for (counter = 0; counter < ceiling; counter++) {
      arr[counter] = num1;
      //printf("%d\n", num1); //prints sequence
      sum = num1+num2;
      num1 = num2;
      num2 = sum;
  }
  return 0;
}
int main (int argc, char const* argv[])
{
    int ceiling = 10;
    int arr[ceiling + 1];
    fibonacci(ceiling, arr);
    return 0;
}

Comments

0

It should return a long*, and arr should be long* that grabs memory from the heap, since a) you want your array to persist after the function returns and b) all of your operands are of type long:

long* fibonacci(int ceiling)
{
  int counter;
  long num1 = 0, num2 = 1, sum; //F is seeded with F(0) = 0, F(1) = 1
  long* arr = malloc((ceiling+1)*sizeof(long));
  //include ceiling in the loop since you have ceiling+1 elements
  for (counter = 0; counter <= ceiling; counter++)
    {
      arr[counter] = num1;
      //printf("%d\n", num1); //prints sequence
      sum = num1+num2;
      num1 = num2;
      num2 = sum;
    }
  return arr;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.