Reputation: 420
I'm trying to familiarize myself with calloc and realloc. I keep getting the below error when the code runs this line:
pb *newPhoneBook = (pb *) realloc(PhoneBook, (10 * sizeof(pb)));
realloc: malloc.c:2842: mremap_chunk: Assertion `((size + offset) & (_rtld_global_ro._dl_pagesize - 1)) == 0' failed.
Aborted (core dumped)
Program runs fine up until this particular line. Am I not using the realloc function correctly?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct phonebook {
char cFirstName[30];
char cLastName[30];
char cNumber[30];
} pb;
int entry();
void convert_u(char *);
int main()
{
int iResponse = 0;
do {
printf("\nPhonebook Menu\n****************\n\n");
printf("1. Enter new contact\n2. Modify existing contact\n3. Exit\n\n");
printf("Please make selection: ");
scanf("%d", &iResponse);
if (iResponse == 1) {
entry();
}
else if (iResponse == 2) {
//modify();
printf("\nWorking on it...\n");
}
} while (iResponse != 3);
return 0;
}
int entry()
{
int x;
char yes_no[] = "YES";
pb Book = {'\0', '\0', '\0'};
pb *PhoneBook = (pb *) calloc(5, sizeof(pb));
PhoneBook = &Book;
if (PhoneBook == NULL) {
printf("\nMemory allocation failed.\n\n");
return 1;
}
for (x = 0; x < 10; x++) {
if (x > 0) {
printf("\nAnother entry(yes/no)? ");
scanf("%s", yes_no);
convert_u(yes_no);
}
if (strcmp(yes_no, "YES") == 0 && x > 0) {
pb *newPhoneBook = (pb *) realloc(PhoneBook, (10 * sizeof(pb))); //fails here
if (newPhoneBook == NULL) {
printf("\nOut of memory!\n\n");
return 1;
}
else {
PhoneBook = newPhoneBook;
}
}
else if (strcmp(yes_no, "NO") == 0) {
break;
}
printf("\nFirst Name: ");
scanf("%s", PhoneBook[x].cFirstName);
printf("\nLast Name: ");
scanf("%s", PhoneBook[x].cLastName);
printf("\nPhone Number: ");
scanf("%s", PhoneBook[x].cNumber);
}
}
void convert_u(char *yes_no)
{
int x;
for (x = 0; x < strlen(yes_no); x++) {
yes_no[x] = toupper(yes_no[x]);
}
}
Upvotes: 1
Views: 791
Reputation: 882446
No, you are not using realloc
correctly. With regards to your code:
pb Book = {'\0', '\0', '\0'};
pb *PhoneBook = (pb *) calloc(5, sizeof(pb));
PhoneBook = &Book;
While that second line sets PhoneBook
to an address in the memory arena (i.e., one that can be passed to realloc
), the third line causes it to point at an item outside of the arena.
Calling realloc
with that pointer is undefined behaviour.
I'm not entirely certain what your intent is there with that third line. If it's to ensure that the fields are initialised to NUL characters, calloc
already does that.
Upvotes: 3
Reputation: 24102
The problem is here:
pb *PhoneBook = (pb *) calloc(5, sizeof(pb));
PhoneBook = &Book;
You allocate space for 5 pb structs, but then you discard that pointer and instead set PhoneBook
to point to Book
, which is on the stack. So you aren't even using the result of calloc
at that point, and you can't realloc
something from the stack.
You could do something like this instead:
pb *PhoneBook = (pb *) calloc(5, sizeof(pb));
PhoneBook[0] = Book;
That will perform a structure copy of Book
into the first element of PhoneBook
. But if you're going to check if calloc
failed, you should do so before the structure copy.
Upvotes: 2