【问题标题】:When realloc, the existing and newly inserted data contain strange valuesrealloc时,现有和新插入的数据包含奇怪的值
【发布时间】:2021-08-13 22:39:43
【问题描述】:

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

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。

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

【问题讨论】:

  • inputBook 在本地更改 books 参数,但调用者看不到更改。您需要返回新值(如reAllocArray)或使用指向指针的指针。
  • 菜单有选择1和2。开关有case 1和5
  • @IanAbbott 谢谢,返回了新值,所以效果很好。
  • 这些教程链接可能有助于解释按值传递函数参数和按引用传递函数参数之间的区别:Call by ValueCall by Reference
  • @AndreasWenzel 非常感谢,很有帮助。

标签: arrays c memory


【解决方案1】:

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

        books = reAllocArray(books, *size);

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

为了与inputBook 的其他参数保持一致,我建议将books 参数的类型更改为BOOK ** 并更改menu 以传递其books 变量的地址,就像它为@987654332 所做的那样@和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;

    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-28
    • 1970-01-01
    • 1970-01-01
    • 2012-07-26
    • 1970-01-01
    • 2010-10-16
    • 2019-06-14
    • 2014-02-06
    相关资源
    最近更新 更多