2

I tried to create dynamically growing array I did with realloc. I have example below but I do not understand how this code works by using malloc.

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

int main(void) {
    int cnt = 0;
    double *numbers = NULL;
    double newnum;
    while (scanf("%lf", &newnum) == 1 && newnum != -1) {
        double *newarr = (double*) malloc(sizeof(double) * (cnt+1)); 
        for (int i = 0; i < cnt; ++i)
            newarr[i] = numbers[i]; 
        free(numbers); 
        numbers = newarr;
        numbers[cnt] = newarr; 
        ++cnt;
    }

    for (int i = cnt-1; i >= 0; --i) {
        printf("%f\n", numbers[i]);
    }

    free(numbers);

    return 0;
}
2
  • Pretty sure that numbers[cnt] = newarr; is supposed to be numbers[cnt] = newnum; Commented Oct 27, 2018 at 8:18
  • 1
    You might like to read stackoverflow.com/questions/605845/… Commented Oct 27, 2018 at 8:37

1 Answer 1

2

realloc() is the same as malloc(), memcpy(), free() all in one function (*).

The loop in your code effectively replaces memcpy()

        // memcpy(newarr, numbers, cnt * sizeof *newarr);
        for (int i = 0; i < cnt; ++i)
            newarr[i] = numbers[i]; 

(*) realloc() may be smart enough to avoid the memcpy() and free() and reuse memory.


How can I implement this in my code?

It helps to encapsulate the pointer and the total/used elements in a structure.

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

struct DynArray {
    double *data;
    size_t m; // total
    size_t n; // used
};

void growarray(struct DynArray *x) {
    size_t newsize = x->m * 13 / 8 + 1; // use phi aproximation 13/8
    double *newarr = realloc(x->data, newsize * sizeof *x->data);
    if (!newarr) exit(EXIT_FAILURE);
    fprintf(stderr, "INFO: realloc'ed with %d elements.\n", (int)newsize);
    x->data = newarr;
    x->m = newsize;
}

int main(void) {
    struct DynArray numbers = { 0 };
    double newnum;
    while (scanf("%lf", &newnum) == 1 && newnum != -1) {
        if (numbers.n == numbers.m) growarray(&numbers);
        numbers.data[numbers.n] = newnum;
        numbers.n++;
    }

    for (int i = numbers.n - 1; i >= 0; --i) {
        printf("%f\n", numbers.data[i]);
    }

    free(numbers.data);

    return 0;
}

See code running on ideone or previous version without growarray function or previous version with cnt

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

5 Comments

I understood. It seems it is better to use realloc.
Also realize that memory allocation is a slow operation and you should instead use a x2, or better, golden ratio to double or ~x1.618 your array size respectively, when you do need more space, and not every single iteration...
@EmilBədrəddinli: nicely spotted!! cnt is a left over from the original code. It was replaced by numbers.n. It is safe to delete and I've edited my answer.
Clearly explained. Thanks

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.