YIGeon
YIGeon

Reputation: 57

When realloc, the existing and newly inserted data contain strange values

The dynamic memory takes the initial size input, then automatically increases it when it fills up, and then new data is entered. If you check the values in the array, there are strange values.

int main() {
    BOOK *books = NULL;
    int count = 0;
    int size = -1;
    menu(books, size, count);
    return 0;
}



void menu(BOOK *books, int size, int count) {

    printf("input initial size.\n");
    scanf("%d", &size);
    while (getchar() != '\n');
    books = allocArray(size);
    if (books == NULL) {
       return;
    }
    while (1) {
        printf("========menu========\n");
        printf("1. input book data\n");
        printf("2. books\n");
        int selector = -1;
        scanf("%d", &selector);
        switch (selector) {
            case 1:
                inputBook(books, &count, &size);
                break;
            case 2:
                showAllBooks(books, count);
                break;
            default:
                free(books);
                books = NULL;
                return;
        }
   }
}

void inputBook(BOOK *books, int *count, int *size) {
    if (*count == *size) {
        printf("--------realloc +5\n");
        *size = *size * 5;
        books = reAllocArray(books, *size);

    }
    printf("--------input--------\n");
    while (getchar() != '\n');
    printf("title :");
    scanf("%s", books[*count].title);

    printf("author :");
    scanf("%s", books[*count].author);

    printf("price :");
    scanf("%d", &books[*count].price);
    *count = *count + 1;

    }

BOOK *allocArray(int size) {
    BOOK *books = NULL;
    books = (BOOK *) malloc(sizeof(BOOK) * size);
    if (books == NULL) {
    printf("malloc fail\n");
    } else {
        memset(books, 0, sizeof(BOOK) * size);
    }
    return books;
}

BOOK *reAllocArray(BOOK *books, int size) {
    BOOK *temp = (BOOK *) realloc(books, sizeof(BOOK) * size);
    if (temp == NULL) {
    printf("realloc fail\n");
    }
    return temp;
}

void showAllBooks(BOOK *books, int count) {
    for (int i = 0; i < count; ++i) {
        printf("%d. title: %s author: %s proce: %d\n", i + 1, books[i].title, books[i].author, books[i].price);
    }
}

When the initial size is set to 1, then 1, 1, 1 data is input and additional data is input. realloc happens and I input 2, 2, 2 If you check the array, it contains 1,1,1 and null, null, and 0.

If more data is previously entered, the existing data may also be damaged.

Upvotes: 0

Views: 35

Answers (1)

Ian Abbott
Ian Abbott

Reputation: 17403

In inputBook, the value of books may changed inside the function to point to a reallocated memory block:

        books = reAllocArray(books, *size);

However, that does not change the corresponding books variable in menu because function parameters in C are passed by value. (OP must already be aware of that since they are using pointers for the other parameters of inputBook.)

For consistency with the other parameters of inputBook, I recommend change the type of the books parameter to BOOK ** and changing menu to pass the address of its books variable as it does for count and size:

(in menu):

                inputBook(&books, &count, &size);
void inputBook(BOOK **pbooks, int *count, int *size) {
    BOOK *books = *pbooks;
    if (*count == *size) {
        printf("--------realloc +5\n");
        *size = *size * 5;
        books = reAllocArray(books, *size);
        *pbooks = books;
    }
    printf("--------input--------\n");
    while (getchar() != '\n');
    printf("title :");
    scanf("%s", books[*count].title);

    printf("author :");
    scanf("%s", books[*count].author);

    printf("price :");
    scanf("%d", &books[*count].price);
    *count = *count + 1;

    }

Upvotes: 3

Related Questions