2016-01-04 1 views
1

Я пытаюсь ознакомиться с calloc и realloc. Я продолжаю получать ошибку ниже, если код работает по этой строке:Ошибка сброса ядра Realloc в C

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) 

Программа работает до этой конкретной линии. Я не использую функцию realloc правильно?

#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]); 
    } 
} 
+0

Пожалуйста, пожалуйста, пожалуйста: Общее правило - это типы StartWithCapitals variables_do_not. вы делаете обратный код, который трудно прочитать. – John3136

+1

@ John3136, это стилистическое руководство и не имеет абсолютно никакого отношения к C-языку как таковому. Идентификаторы (из которых типы и переменные равны двум) следуют * одинаковым * правилам. На самом деле, я часто делаю такие вещи, как 'typedef struct sSomething {...} tSomething;', который достаточно читаем :-) – paxdiablo

+0

@paxdiablo Да, ваше право. Это стиль. Мы оба знаем, что существует более одного работоспособного стиля, но стиль OPs - это не тот, который мы ожидаем увидеть как профессионалы, что означает, что их код трудно читать и поддерживать другим. Я думаю, что это разумный комментарий (а не ответ) - надеюсь, что он прочитает его и что-то узнает. – John3136

ответ

3

Нет, вы не используете realloc правильно. Что касается вашего кода:

pb Book = {'\0', '\0', '\0'}; 
pb *PhoneBook = (pb *) calloc(5, sizeof(pb)); 
PhoneBook = &Book; 

Пока что второй линии устанавливает PhoneBook на адрес на арене памяти (то есть один, который может быть передан realloc), то третьей линия заставляет его указать на предмет за пределами арены.

Вызов realloc с указанным указателем является неопределенным поведением.

Я не полностью не знаю, что у вас есть с этой третьей линией. Если это необходимо для того, чтобы поля были инициализированы символами NUL, calloc уже делает это.

2

Проблема здесь:

pb *PhoneBook = (pb *) calloc(5, sizeof(pb)); 
PhoneBook = &Book; 

Вы выделить место для 5 П.Б. структур, а затем выбросить этот указатель и вместо того, чтобы установить PhoneBook, чтобы указать на Book, который находится в стеке. Таким образом, вы даже не используете результат calloc в этот момент, и вы не можете сделать realloc что-то из стека.

Вы могли бы сделать что-то вроде этого, вместо:

pb *PhoneBook = (pb *) calloc(5, sizeof(pb)); 
PhoneBook[0] = Book; 

Это будет выполнять структурную копию Book в первый элемент PhoneBook. Но если вы собираетесь проверить, не удалось ли calloc, вы должны сделать это до копирования структуры.