无法根据用户字符串动态分配内存; realloc(): 下一个大小无效

Failed to dynamically allocate memory based on user's string; realloc(): invalid next size

我正在尝试最小化以下程序的内存分配。我尝试动态分配内存的整个想法是

  1. 为用户输入的 30 字节字符串动态分配内存
  2. 如果用户的输入大于分配的内存,调用realloc()函数使字符串适应101字节
  3. 如果用户的输入大于 100 字节,调用 exit() 并终止程序。

当我实现 realloc() 函数以检查用户输入是否适合动态分配的 char 数组(与 calloc 一致)时,我的程序失败并显示以下输出:

realloc(): invalid next size
Aborted (core dumped)

我不知道怎么解决。

代码:

#include <stdio.h>  //gets() was removed from this library
#include <stdlib.h> //for calloc()
#include <string.h> //for strlen()
#include <unistd.h> //for sleep(2)
int len = 0;
struct item
{
    //i cant make sure pointer points to nothing because structures are only a templates.
    //i cant do operations here!!!!!!!
    char *itemName;
    int qty;
    float price;
    float amount;
};

int readItem(struct item *pProduct)

{
    printf("hey, what is the product name: ");
    gets(pProduct->itemName);

    //checking whether user's input fits into the allocated pointer size
    len = strlen(pProduct->itemName);
    printf("%d\n\n", len);

    if (len > 30)
    {
        //error here
        pProduct->itemName = (char *)realloc(pProduct->itemName, 101);

        printf("\nyour input is too big. re enter it\n");
        gets(pProduct->itemName);

        if (pProduct->itemName == NULL)
        {
            puts("memory is not avaible");
            exit(1);
        }
        len = strlen(pProduct->itemName);
        printf("%d\n\n", len);
        if (len > 100)
        {
            puts("memory is not avaible");
            exit(1);
        }
    }
    printf("\nEnter the product quantity: ");
    scanf("%d", &pProduct->qty);

    printf("\nEnter the product price: ");
    scanf("%f", &pProduct->price);

    //calculating the amount
    pProduct->amount = (float)pProduct->qty * pProduct->price;

    return 0;
}

void printItem(struct item *pProduct)
{
    puts("\n\nthe database:");
    sleep(1);

    printf("----------------------\n");
    printf("Name: \"%s\"\n", (*pProduct).itemName);
    printf("Price: %.2f\n", pProduct->price);
    printf("Quantity: %d\n", pProduct->qty);
    printf("Amount: %.2f\n", pProduct->amount);
    printf("----------------------\n");
}

int main()
{

    //assigning variable product and piinter pProduct to a tag name item,
    struct item product, *pProduct = NULL;
    //storing an address to a pointer pProduct
    //making a structure to a pointer
    pProduct = &product;

    //(char *) is casting char to a pointer type

    pProduct->itemName = (char *)calloc(30, sizeof(char));

    readItem(pProduct);
    printItem(pProduct);

    free(pProduct->itemName);
    pProduct->itemName = NULL;
    pProduct = NULL;

    return 0;
}

我确切地知道 REALLOC 导致了麻烦。更准确地说,如果我输入 34 个字符,realloc 似乎有效,但如果将其加倍到 68,尽管在 realloc

中提到了大小,它仍会抛出错误

我对调用堆栈的了解为零,但它可能对某人有用:


    libc.so.6!__GI_raise(int sig) (/build/glibc-YYA7BZ/glibc-2.31/sysdeps/unix/sysv/linux/raise.c:50)
     
    libc.so.6!__GI_abort() (/build/glibc-YYA7BZ/glibc-2.31/stdlib/abort.c:79)
     
    libc.so.6!__libc_message(enum __libc_message_action action, const char * fmt) (/build/glibc-YYA7BZ/glibc-2.31/sysdeps/posix/libc_fatal.c:155)
     
    libc.so.6!malloc_printerr(const char * str) (/build/glibc-YYA7BZ/glibc-2.31/malloc/malloc.c:5347)

    libc.so.6!_int_realloc(mstate av, mchunkptr oldp, size_t oldsize, size_t nb) (/build/glibc-YYA7BZ/glibc-2.31/malloc/malloc.c:4564)
     
    libc.so.6!__GI___libc_realloc(size_t bytes, void * oldmem) (/build/glibc-YYA7BZ/glibc-2.31/malloc/malloc.c:3226)
     
    libc.so.6!realloc_hook_ini(void * ptr, size_t sz, const void * caller) (/build/glibc-YYA7BZ/glibc-2.31/malloc/hooks.c:41)
     
    readItem(struct item * pProduct) (/home/max/My stuff/programming/Udemy/section 14, reading and wrinting files/test.c:22)
     
    main() (/home/max/My stuff/programming/Udemy/section 14, reading and wrinting files/test.c:72)
</pre>
	

建议;

分配一个长缓冲区,比可能需要的时间长得多。然后通过调用 fgets()

获取数据
char buffer[1024];
fgets( buffer, sizof( buffer ), stdin );

-或-

使用getline()函数读取数据

char *buffer = NULL;
size_t byteCount;
getline( &line, &byteCount, stdin );

注意:为了简化说明,我没有检查上面的错误。