I am attempting to minimize the memory allocation for the following program. The whole idea behind my attempt to dynamically allocate memory is
- Dynamically allocate memory for a user's string input with 30 bytes
- If the user's input is bigger than the allocated memory, call realloc() function to fit the string with 101 bytes
- If the user's input is bigger than 100 bytes, call exit() and terminate the program.
When I implemented realloc() function to check whether user input fits into dynamically allocated char array (line with calloc), my program fails with the following output:
realloc(): invalid next size
Aborted (core dumped)
I am not sure how to resolve it.
Code:
#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;
}
I know precisely REALLOC causes the trouble. To be more precise, if I enter 34 characters realloc seems to work, but if double it to 68, it throws the error despite the mentioned size in realloc
I have zero knowledge in call stack, but it might be useful for someone:
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)