Search code examples
carrayspointersrealloc

Re allocating C array for more space


Im writing a program with a function add(a , i, n) which will add 'i' as an element to 'a', but if the array 'a' runs out of space, then I need to realloc more memory to the array. Im stuck here:

#include <stdlib.h>
#include <stdio.h>

int add(int* a, int i, int n);

int main(){
    int n = 20;
    int *a = (int*) malloc(n*sizeof(int));
    int i;

    for (i = 0; i < 100000; i++){
        n = add(a, i, n);
        printf("a[%d]=%d\n",i,(int)a[i]);
    }
    return 0;
}

int add(int *a, int i, int n){
    if (i >= n){
        n++;
        int* b = (int*) realloc(a, n*sizeof(int));
        a[i]=i;
        return n;
    }else{
    }
}

Im not very experienced so please be gentle...


Solution

  • realloc tries to reallocate the given memory, but sometimes, it can't and gives you a new memory pointer.

    It must be used like:

    int *b;
    b = realloc(a, <newsize>);
    if (b) {
        /* realloc succeded, `a` must no longer be used */
        a = b;
        /* now a can be used */
        printf("ok\n");
    } else {
        /* realloc failed, `a` is still available, but it's size did not changed */
        perror("realloc");
    }
    

    Now, you still have some trouble in your code:

    The idea of function add() is to reallocate a when needed, but a is given by copy, so its value won't be changed in main.

    #include <stdlib.h>
    #include <stdio.h>
    
    int add(int** a, int i, int n);
    
    int main(){
        int n = 20;
        int *a = malloc(n*sizeof(int));
        int i;
    
        for (i = 0; i < 100000; i++) {
            /* note how `a` is passed to `add` */
            n = add(&a, i, n);
            printf("a[%d]=%d\n",i,a[i]);
        }
        /* and finally free `a`*/ 
        free(a);
        return 0;
    }
    
    /* changed `a` type to make its new value visible in `main` */
    int add(int **a, int i, int n){
        if (i >= n){
            /* want to write a[i], so size must be at least i+1*/
            n = i+1;
            /* realloc memory */
            int *b = realloc(*a, n*sizeof(int));
    
            /* check that `realloc` succeded */
            if (!b) { 
                /* it failed!*/
                perror("realloc"); 
                exit(1);
            } 
            /* store new memory address */
            *a = b;
        }
    
        /* update memory */        
        (*a)[i]=i;        
    
        /* return new size */
        return n;
    }
    

    Note: I removed malloc/realloc cast, see: Do I cast the result of malloc?