首页 > 解决方案 > realloc时,现有和新插入的数据包含奇怪的值

问题描述

动态内存取初始大小输入,然后在填满时自动增加,然后输入新数据。如果你检查数组中的值,会有奇怪的值。

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);
    }
}

当初始大小设置为 1 时,则输入 1、1、1 个数据并输入附加数据。realloc 发生,我输入 2, 2, 2 如果检查数组,它包含 1,1,1 和 null、null 和 0。

如果之前输入了更多数据,则现有数据也可能被损坏。

标签: arrayscmemory

解决方案


inputBook中,函数内部的值books可能会更改为指向重新分配的内存块:

        books = reAllocArray(books, *size);

但是,这不会改变相应的books变量,menu因为 C 中的函数参数是按值传递的。(OP 必须已经意识到这一点,因为他们正在使用 . 的其他参数的指针inputBook。)

为了与 的其他参数保持一致inputBook,我建议将books参数的类型更改为BOOK **并更改menu为传递其books变量的地址,就像对countand所做的那样size

(在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;

    }

推荐阅读