问题
Currently trying to write menu based program that asks user for student records, after initial records are entered I want user to have option to add more record slots but when I try to realloc my 2d pointer array my program crashes, specifically after the 2nd function is called.
#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]);
}
回答1:
EDIT there is an error in a missing ;
resulting in lastName
not being reallocated
if (a != NULL) //realloc was successful
firstName = a;
else //there was an error <<-- missing ;
a = (char **)realloc(lastName, *size * sizeof(char*)); // <<-- executed under "else"
In fact, lastName
is assigned the same value as firstName
with the following
if (a != NULL) //realloc was successful
lastName = a;
Also, a comment about about your use of check
. There are some things wrong with your input loop. It's quite unnecessary to allocate memory for a simple int
. You aren't even using check
as a pointer (check = 0;
will cause free()
to fail, and a memory leak).
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);
This would be much easier, and you don't even need 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);
回答2:
C is pass by value.
The changes applied to firstName
and lastName
in addREcord()
are lost after the function returned, as those two vairbales carry copeis of the variables passed as argument to the call of addRecord()
.
Change the definition of addRecord()
from
void addRecord(int* size, char** firstName, char** lastName, float* grade);
to be
void addRecord(int* size, char*** pfirstName, char*** plastName, float* grade);
and inside addRecord()
replace all firstName
with (*pfirstName)
and all lastName
with (*plastName)
(Interessting enough you did the correctly for size
.)
Call addRecord()
like this:
addRecord(&size, &firstName, &lastName, grade);
来源:https://stackoverflow.com/questions/29776167/realloc-causing-program-to-crash