Thread: Fibonacci Sequence with Dynamic Memory

  1. #1
    Registered User
    Join Date
    Apr 2016
    Posts
    48

    Fibonacci Sequence with Dynamic Memory

    I'm trying to create the Fibonacci Sequence in C using dynamic memory allocation but I can not manage to update the array size for every new number. I also do not how to use malloc and realloc in a good way yet. Can anybody give some help ?

    This is what I tried:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int *fib;
        int i = 2;
        
        fib = (int *) malloc(1 + sizeof(int));
        fib[0] = 1;
        
        fib = (int *) realloc(fib, +1);
        fib[1] = 1;
        
        int i = 2;
        
        while(1)
        {
            fib = (int *) realloc(fib, +1);
            fib[i] += fib[i-1];
            i++;
            printf("%d\n", fib[i]);
        }
           
    }

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    I guess purely for exercise sake this is a good way to learn realloc(), but you really shouldn't keep allocating forever (i.e. while(1) ...); just compute up to say 20th term, instead.
    Code:
    // you need a variable representing the maximum size of the current array 
    int cap = 16;
    // check BEFOREHAND that you have room for a new number; if not, allocate some more
    if (i == cap) {
       int *temp = realloc(fib, cap = i * 2);
       if (temp != NULL) { 
          fib = temp;
       }
       else {
          fprintf("error: can't allocate fib anymore\n");
          exit(EXIT_FAILURE);
       }
    }
    Last edited by whiteflags; 07-28-2016 at 09:33 PM.

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Building off of whiteflags' post:

    • Don't cast malloc.
    • Always check the return value of malloc/calloc/realloc. They do sometimes fail, in which case they return null. If you don't check the return value, you will end up trying to dereference a null pointer when you use the memory that wasn't actually allocated, and you'll end up with undefined behavior.
    • Always use a temp pointer when using realloc. If you don't, and realloc fails, you lose the original pointer, which means you lose the data and you have a memory leak. Doubly bad.
    • You don't need to add 1 in your first malloc statement (it's adding a single byte that you aren't really using).
    • You can't just say "+1" to get more memory. That is telling realloc to only give you back a single byte. You have to tell realloc how many bytes total you want to realloc to.
    • You should use something like num_elements * sizeof(*fib) when telling malloc/realloc how much memory you want. That way, if you change fib to a long or long long type, you don't have to worry about changing the malloc, it will always give you the right amount of memory.
    • Whiteflags' code hints at this, but start with a reasonable fixed number of elements, then grow by some factor as you need more. Unless you're on a low-memory system, it's okay to have a few bytes of unused memory lying around.
    • Read the documentation for malloc/realloc. It's always good to know as much as you can about the functions you're using.
    • Always remember to free the memory when you're done with it.


    I usually do something like:
    Code:
    #define DESIRED_SEQ_LEN 25  // how many terms you want to compute in total
    int max_elements = 10;  // arbitrary, pick a sensible value for your situation
    int *fib = NULL;
    
    fib = malloc(max_elements * sizeof(*fib));
    if (fib == NULL) {
      perror("Error allocating memory for fib: ");
      exit(EXIT_FAILURE);
    }
    
    fib[0] = 1;
    fib[1] = 1;
    for (int i = 2; i < DESIRED_SEQUENCE_LEN; i++) {
      if (i >= max_elements) {
        int *new_max_elements = max_elements * 2;
        int *temp = realloc(fib, sizeof(*fib) * new_max_elements);
        if (temp == NULL) {
          perror("Error reallocating memory for fib: ");
          free(fib);
          exit(EXIT_FAILURE);
        }
        max_elements = new_max_elements;
        fib = temp;
      }
      fib[i] = ???  // note, your current fib[i] += fib[i-1] is wrong; I'll let you figure out the correct way
    }
    ...
    free(fib);

  4. #4
    Registered User
    Join Date
    Apr 2016
    Posts
    48
    I casted Malloc because I read and saw videos about dynamic memory where the person would cast malloc, realloc and calloc. Why Should I not ?

    Code:
    int *new_max_elements = max_elements * 2;int *temp = realloc(fib, sizeof(*fib) * new_max_elements);
    This part doubles the fib array,right ? Is there a way to just add one more int memory space for the array with realloc ?

    I implemented what you guys wrote but when it reaches the maximum element, the program crashes. I can not undestand why.

    This is how it is:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #define DESIRED_SEQ_LEN 25  // how many terms you want to compute in total
    
    int main(){
        
    int i = 0;
    int max_elements = 10;  // arbitrary, pick a sensible value for your situation
    int *fib = NULL;
     
    fib = malloc(max_elements * sizeof(*fib));
    
    if (fib == NULL) 
    {
        perror("Error allocating memory for fib: ");
         exit(EXIT_FAILURE);
    }
     
    printf("Fibonacci Sequence is:\n");
     
    fib[0] = 1;
    fib[1] = 1;
    printf("%d\n", fib[0]);
    printf("%d\n", fib[1]);
    
    for (i = 2; i < DESIRED_SEQ_LEN; i++) {
        if (i >= max_elements) 
        {
            int *new_max_elements = max_elements * 2;
            int *temp = realloc(fib, sizeof(*fib) * (*new_max_elements));
            if (temp == NULL) 
            {
                  perror("Error reallocating memory for fib: ");
                  free(fib);
                  exit(EXIT_FAILURE);
            }
        
        max_elements = new_max_elements;
        fib = temp;
          
        }
        
        fib[i] = fib[i-1] + fib[i-2];
          printf("%d\n", fib[i]);
    }
    
    free(fib);
    
    return 0;
    }

  5. #5
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    I casted Malloc because I read and saw videos about dynamic memory where the person would cast malloc, realloc and calloc. Why Should I not ?
    Casting malloc() isn't necessary, that's basically why you should not do it. At worst, it can cover up programming mistakes. You really should read the links posted in post #3 of this thread. You might also want to read this post.
    his part doubles the fib array,right ? Is there a way to just add one more int memory space for the array with realloc ?
    Yes, if you learn why the example code works then adjusting the array size one element at a time is easy, but you shouldn't want to do that. It's basically an abuse of the malloc implementation. You will fragment your heap and cause allocations to work progressively slower.
    I implemented what you guys wrote but when it reaches the maximum element, the program crashes. I can not undestand why.
    I think the code you copied from had some typographical errors inserted on purpose to prevent you from copying it completely.
    Code:
    C:\Users\jk\Desktop>gcc -std=c99 -Wall -g -o fib.exe fib.c
    fib.c: In function 'main':
    fib.c:29:33: warning: initialization makes pointer from integer without a cast [enabled by default]
             int *new_max_elements = max_elements * 2;
                                     ^
    fib.c:38:18: warning: assignment makes integer from pointer without a cast [enabled by default]
         max_elements = new_max_elements;
    Mistakes with pointers like this are enough to cause a crash.
    Last edited by whiteflags; 07-30-2016 at 07:25 PM.

  6. #6
    Registered User
    Join Date
    Apr 2016
    Posts
    48
    Oh, I did not notice the links at first. Now I understood the casting problem fine. I fixed the program now, working fine it seems. Or is there something I did wrong ?

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #define limit 20  
    
    int main(){
        
    int i = 0;
    int max = 10;  
    int *fib = NULL;
     
    fib = malloc(max * sizeof(*fib));
    
    if (fib == NULL) 
    {
        perror("Error allocating memory for fib: ");
         exit(EXIT_FAILURE);
    }
     
    printf("Fibonacci Sequence is:\n");
     
    fib[0] = 1;
    fib[1] = 1;
    printf("%d\n", fib[0]);
    printf("%d\n", fib[1]);
    
    for (i = 2; i < limit; i++) {
        if (i >= max) 
        {
            int new_max = max + 1;
            int *temp = realloc(fib, sizeof(*fib) * (new_max));
            if (temp == NULL) 
            {
                  perror("Error reallocating memory for fib: ");
                  free(fib);
                  exit(EXIT_FAILURE);
            }
        
        max = new_max;
        fib = temp;
          
        }
        
        fib[i] = fib[i-1] + fib[i-2];
          printf("%d\n", fib[i]);
    }
    
    free(fib);
    
    return 0;
    }

  7. #7
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Sorry, typographical errors were not on purpose, but yes, a good reason not to copy-paste without reading carefully to understand it first.

  8. #8
    Registered User
    Join Date
    Apr 2016
    Posts
    48
    Then thanks for the help !

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. 5 - Fibonacci Sequence
    By cmp in forum C Programming
    Replies: 7
    Last Post: 03-08-2014, 06:18 PM
  2. Fibonacci Sequence
    By nicole0808 in forum C Programming
    Replies: 8
    Last Post: 02-20-2014, 02:02 PM
  3. fibonacci sequence
    By cph in forum C Programming
    Replies: 57
    Last Post: 04-30-2009, 07:17 AM
  4. Fibonacci sequence
    By MuffanMan123 in forum C++ Programming
    Replies: 6
    Last Post: 02-26-2008, 09:15 AM
  5. Fibonacci sequence
    By girliegti in forum C++ Programming
    Replies: 8
    Last Post: 09-30-2003, 10:40 PM

Tags for this Thread