Realloc导致程序崩溃

时间:2015-04-21 15:08:58

标签: c malloc realloc

目前正在尝试编写基于菜单的程序,要求用户输入学生记录,在输入初始记录后,我希望用户可以选择添加更多记录槽但是当我尝试重新分配我的2d指针数组时,我的程序崩溃,特别是在第二个函数被调用。

#include <stdio.h> 
#include <string.h>
#include <stdlib.h>
#define LENGTH 21
void printRecords(int* size, char **fistName, char **lastName, float *grade);
void addRecord(int* size, char** firstName, char** lastName, float *grade);

int  main(void) { /* Minimum measure check */
    int size = 0, *check = (int*)malloc(sizeof(int));
    *check = 1;
    while (check) {
        printf("Please indicate number of records you want to enter (min 5): ");
        scanf("%d", &size);
        if (size < 5)
            printf("Size entered was below the minimum.\n");
        else
            check = 0; }
    free(check);

                                        /* Dynamic Memory Allocation */
    char **firstName = (char**)malloc(size * sizeof(char*)), **lastName = (char**)malloc(size * sizeof(char*)); 
    float *grade = (float*)malloc(size * sizeof(float));

    int i;
    for (i = 0; i < size; i++) {
        firstName[i] = (char*)malloc(LENGTH *  sizeof(char));
        lastName[i] = (char*)malloc(LENGTH * sizeof(char)); }

    printf("Please input records of students (enter a new line after each record),\nwith following format first name last name score:\n");
    for (i = 0; i < size; (i)++)
        scanf("%s %s %f", &firstName[i][0], &lastName[i][0], &grade[i]);

    int option = 1;
    while (option != 0) { /* Option Menu */
        printf("Print records (press 1)\nAdd new record(press 2)\nDelete record(s)(press 3)\nSeach by last name(press 4)\nSort by score(press 5)\nSort by last name(press 6)\nFind the median score(press 7)\nExit the program(press 0)\n");
        scanf("%d", &option);

        switch (option) {
        case 1:
            printRecords(&size, firstName, lastName, grade);
            break;
        case 2:
            addRecord(&size, firstName, lastName, grade);
            break;
        case 3:
            break;
        case 4:
            break;
        case 5:
            break;
        case 6:
            break;
        case 7:
            break;
        }
    }
    return 0;
}

void printRecords(int* size, char **firstName, char **lastName, float grade[]) { /* Option 1 */
            int i;
            for (i = 0; i < *size; i++)
                printf("First Name : %s, Last Name : %s, Score : %.2f\n", firstName[i], lastName[i], grade[i]); 
    }

void addRecord(int* size, char** firstName, char** lastName, float* grade) { /* Option 2 */
    char **a;
    float *c;
    (*size) += 1;

    a = (char **)realloc(firstName, *size * sizeof(char*)); /* Error */
    if (a != NULL) //realloc was successful
        firstName = a;
    else //there was an error

    a = (char **)realloc(lastName, *size * sizeof(char*));
    if (a != NULL) //realloc was successful
        lastName = a;
    else; //there was an error 

    c = (float *)realloc(grade, *size * sizeof(float*));
    grade = c;
    firstName[*size - 1] = (char*)malloc(LENGTH * sizeof(char));
    lastName[*size - 1] = (char*)malloc(LENGTH * sizeof(char));
    scanf("%s %s %f", &firstName[*size][0], &lastName[*size][0], &grade[*size]);
    }

2 个答案:

答案 0 :(得分:1)

编辑缺少;时出错,导致lastName未重新分配

if (a != NULL) //realloc was successful
    firstName = a;
else //there was an error                                  <<-- missing ;

a = (char **)realloc(lastName, *size * sizeof(char*));  // <<-- executed under "else"

事实上,lastName的分配值与firstName相同,后面带有

if (a != NULL) //realloc was successful
    lastName = a;

另外,关于您使用check的评论。输入循环有些问题。为简单的int分配内存是非常必要的。您甚至没有使用check作为指针(check = 0;会导致free()失败,并导致内存泄漏。)

int size = 0, *check = (int*)malloc(sizeof(int));
*check = 1;
while (check) {         // <==== error should be *check
    printf("Please indicate number of records you want to enter (min 5): ");
    scanf("%d", &size);
    if (size < 5)
        printf("Size entered was below the minimum.\n");
    else
        check = 0;      // <==== error should be *check
    }
free(check);

这会更容易,您甚至不需要check

int size;
do {
    printf("Please indicate number of records you want to enter (min 5): ");
    scanf("%d", &size);
    if (size < 5)
        printf("Size entered was below the minimum.\n");
    }
while (size < 5);

答案 1 :(得分:1)

C是按值传递的。

在返回函数后,应用于firstName中的lastNameaddREcord()的更改将丢失,因为这两个vairbales将作为参数传递的变量的copeis传递给{{1 }}

更改addRecord()的定义
addRecord()

void addRecord(int* size, char** firstName, char** lastName, float* grade);

void addRecord(int* size, char*** pfirstName, char*** plastName, float* grade); 内部将所有addRecord()替换为firstName,将所有(*pfirstName)替换为lastName

(足够有力地为(*plastName)正确地做了。)

像这样呼叫size

addRecord()