重新分配一个更大的元素 (2x) 时 C 程序崩溃
C Program Crashing when Reallocing One Element Larger (2x)
我是 C 语言的初学者,我正在尝试以最简单的方式学习动态内存分配 - 我有一个管理学生记录的程序,但我有一些我一生都无法解决的问题即使在 googleing/Whosebuging 几个小时之后 -- 这是这个程序要完成的:
- 接收学生记录
- 添加和删除记录(这些命令不起作用)
- 对学生记录进行排序
- 从这些记录中找到一些额外的值
这是在 GDB 调试器中发现的导致此错误的原因(问题来自 addRecord 函数和 freeMemory 函数):
*** Error in `/home/a.out': realloc(): invalid next size:
0x0000000000c42060 ***
Aborted
并且当在 GDB 调试器之外使用 GCC 和 运行 编译时,它只会出现段错误。
只有当我在程序中执行这些选项时才会发生这种情况:
1) 添加一条记录
2) 删除记录
3) 添加一条记录(然后崩溃)
或
1) 添加一条记录
2) 添加一条记录(然后崩溃)
我不确定是什么原因造成的,我也不知道如何解决,谁能帮我指明正确的方向?我尝试在 freeMemory 函数中 realloc 成功后添加一个 free 但无济于事,这会导致程序在删除添加的记录时崩溃。
代码如下:
#include <stdio.h>
#include <stdlib.h>
// Declare functions:
void printMenu();
void printRecords(char** fn, char** ln, float* s);
void addRecord(char** fn, char** ln, float* s);
void deleteRecord(char** fn, char** ln, float* s);
int freeMemory(char** fn, char** ln, float* s, char* n, int matches);
int findName(char** ln,char* n);
static int records; // global records variable
int main(){
int i, j;
int choice;
int option = -1;
printf("WELCOME TO THE STUDENT RECORD MANAGER 100 V 1.0! \n");
printf("Please indicate the number of student records you want to enter (min 5, max 15): \n");
scanf("%d",&records);
if(records < 5 || records > 15){
printf("You must enter more than five and less than 15... terminating. \n");
return 0;
}
// Declare arrays
char** firstNames;
char** lastNames;
float* scores;
// Declare variables
char* search = malloc(64);
firstNames = malloc(records*sizeof(*firstNames));
lastNames = malloc(records*sizeof(*lastNames));
scores = malloc(records*sizeof(float));
printf("Please enter the records now (ex. firstName lastName score ENTER):\n");
// Gather Records
for(i = 0; i < records; i ++){
printf("%d ",i+1);
firstNames[i] = malloc(254 * sizeof(char));
lastNames[i] = malloc(254 * sizeof(char));
//scores[i] = malloc(sizeof(float));
scanf("%s %s %f",firstNames[i], lastNames[i], &scores[i]);
}
// Generate menu and do actions
do{
printMenu();
scanf("%d",&choice);
switch(choice){
case 1:
printRecords(firstNames, lastNames, scores);
break;
case 2:
addRecord(firstNames, lastNames, scores);
break;
case 3:
deleteRecord(firstNames, lastNames, scores);
break;
case 0:
return 0;
}
}
while(1);
return 0;
}
// Print user menu
void printMenu(){
printf("\tMain Menu\t\n"
"============================\n"
" > Print records (press 1) \n"
" > Add a new record (press 2) \n"
" > Delete a record (press 3) \n"
" > Exit the program (press 0)\n"
"============================\n"
"Please select an option: ");
}
// Print all user records
void printRecords(char** fn, char** ln, float* s){
int i;
printf("THERE ARE %d RECORDS \n",records);
for(i=0;i<records;i++)
printf("(%d) First name: %s | Last name: %s | Score: %0.2f \n",i,fn[i],ln[i],s[i]); // will start at the first item and go i amount in the index
}
// Add user record
void addRecord(char** fn, char**ln, float* s){
char** tempPtr;
float* tempFPtr;
printf("Please input the values that you'd like to add (ex. firstName lastName score ENTER): \n");
if(records+1 < 15){ // if the array is not larger than maximum value when we make it larger
// lets reallocate the arrays
tempPtr = realloc(fn, (records+1)*sizeof(*fn));
if(tempPtr){
printf("ALLOCATION successfully");
fn = tempPtr;
}
else{
printf("FAILED");
// Realloc Failed
}
tempPtr = realloc(ln, (records+1)*sizeof(*ln));
if(tempPtr){
printf("ALLOCATION successfully");
ln = tempPtr;
}
else{
printf("FAILED");
// Realloc Failed
}
/*tempFPtr = realloc(s, records+1*sizeof(float));
if(tempFPtr){
s = tempFPtr;
}*/
printf("There are now %d items.. \n", records);
fn[records] = malloc(64); // in the LAST value of all arrays
ln[records] = malloc(64);
scanf("%s %s %f",fn[records], ln[records], &s[records]);
printf("(%d) > ADDED -> First name: %s | Last name: %s | Score: %0.2f \n",records,fn[records],ln[records],s[records]);
int i;
records++; // increment by one
printf("There are now %d items.. \n", records);
printf(" > Record successfully added.\n");
}
else{
printf(" > You have hit the max amount of records allowed for this program (15).\n");
}
}
// Delete all instances of user record by (last Name)
void deleteRecord(char** fn, char**ln, float* s){
char* lastName = malloc(32 * sizeof(char*));
printf("What is the last name of the student you would like to delete? \n");
scanf("%s", lastName);
// searching for that record
int matches = findName(ln, lastName);
if(matches && records-matches > 4){ // this means it doesn't go below minimum 5
if(freeMemory(fn, ln, s, lastName, matches)){
printf(" > Record successfully deleted.\n");
free(lastName);
}
}
else{
printf(" > Either no matches were found or deleting this value would put the number of records at less than 5. \n");
}
}
// Extension of deleteRecord that does duplication to push 'delete' lastName to the end, then reallocates array to cut it off the end
int freeMemory(char** fn, char** ln, float* s, char* n, int matches){
int i,j;
/* LOGIC:
- REALLOCATE ARRAY BY X LESS SIZE AFTER PUSHING THE VALUES TO BE REMOVED TO THE END
- NEED TO DO THIS FOR THREE ARRAYS
- TO REMOVE:
- RUN THROUGH X AMOUNT OF TIMES PUSHING EACH SPECIFIC REMOVAL VALUE (IE) 1st found match
- TO THE END
SHIFT
- FOUND 1st MATCH
- MATCH = MATCH + 1
- MATCH + ! = MATCH + 2
- ETC UNTIL YOU HAVE A DUPLICATE AT THE END, THEN REALLOCATE BY 1 LESS
*/
char** tempPtr = NULL;
float* tempFPtr = NULL;
for(i=0;i<matches;i++){ // gonna go through as many times as matches
int match = 0;
// let's make sure the name isn't on the end of the array before we do all this junk
if(strcmp(n,*(ln+records-1)) == 0){
printf("FN");
tempPtr = realloc(fn, (records-1)*sizeof(*fn));
if(tempPtr){
fn = tempPtr;
printf("FN PASSED");
//free(fn[records]);
}
else{
// Realloc Failed
printf("FN FAILED");
}
printf("LN");
tempPtr = realloc(ln, (records-1)*sizeof(*ln));
if(tempPtr){
ln = tempPtr;
printf("LN PASSED");
//free(ln[records]);
}
else{
printf("LN FAILED");
// Realloc Failed
}
records--;
}
else{
// lets find the first match by going through each last name
for(j=0;j<records-1;j++){
// Lets find first match
if(strcmp(n,ln[j]) == 0){ // accessing index
// lets start copying
*(ln+j) = *(ln+j+1);
*(fn+j) = *(fn+j+1);
*(s+j) = *(s+j+1);
match = 1;
}
else if(match){
// already copied first val so lets start copying the rest until we get to the end.
*(ln+j) = *(ln+j+1);
*(fn+j) = *(fn+j+1);
*(s+j) = *(s+j+1);
}
}
printf("FN");
tempPtr = realloc(fn, (records-1)*sizeof(*fn));
if(tempPtr){
fn = tempPtr;
printf("FN PASSED");
//free(fn[records]);
}
else{
// Realloc Failed
printf("FN FAILED");
}
printf("LN");
tempPtr = realloc(ln, (records-1)*sizeof(*ln));
if(tempPtr){
ln = tempPtr;
printf("LN PASSED");
//free(ln[records]);
}
else{
printf("LN FAILED");
// Realloc Failed
}
/*tempFPtr = realloc(s, records-1*sizeof(float));
if(tempFPtr){
s = tempFPtr;
printf("S PASSED");
}
else{
printf("s FAILED ");
}*/
records--;
match = 0;
}
}
return 1;
}
// Finds how many instances of a last name are present
int findName(char** ln,char* n){
int i, counter=0;
for(i=0;i<records-1;i++){
if(strcmp(n,*(ln+i)) == 0){
counter++;
}
}
return counter;
}
错误似乎在您的函数中 addRecord
。你有表达式
tempPtr = safe_trim(ln, records+1*sizeof(*ln));
由于 C operator precedence,它给出了 records + (sizeof (*ln))
的大小。乘法先于加法。该行应更改为:
tempPtr = safe_trim(ln, (records + 1) * sizeof(*ln));
还因为 safe_trim
始终 return 一个有效的指针,无论是原始指针还是调整后的指针,此检查
tempPtr = safe_trim(fn, records+1*sizeof(*fn));
if(tempPtr){
printf("ALLOCATION successfully");
fn = tempPtr;
}
else{
printf("FAILED");
// Realloc Failed
}
永远不会遵循 else
分支并且不会处理分配失败。将对 safe_trim
的调用替换为 realloc
应该不会对程序产生任何影响,除非允许检测分配失败。
我已经解决了问题。这是因为我没有使用三重指针,它没有寻址原始变量。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void printMenu();
void printRecords(char** fn, char** ln, double* s);
void addRecord(char ***fn, char ***ln, double **s);
void addString(char ***strArray, char* str);
void addDouble(double** dubArray, double dub);
void deleteRecord(char*** fn, char*** ln, double** s);
void removeString(char ***strArray);
void removeDouble(double** dubArray);
int findName(char** ln,char* n);
int records;
int counter;
int main(){
records = 0;
counter = 1;
int initRecords = 0;
int choice,i;
char **fn; // first Names
char **ln; // last Names
double *s; // score
printf("= =\n"
"Please enter how many value"
"s you would like to initall"
"y enter [min 5, max 15]: ");
scanf("%d", &initRecords);
if(initRecords < 5 || initRecords > 15)
return 0;
// allocate memory
fn = malloc(0); // will reallocate later
ln = malloc(0);
s = malloc(0);
printf("Please enter the value (firstName lastName score ENTER): \n");
for(i = 0;i<(initRecords);i++){
addRecord(&fn, &ln, &s);
counter++;
}
printf("Records added... \n");
do{
printMenu();
scanf("%d",&choice);
switch(choice){
case 1:
printRecords(fn, ln, s);
break;
case 2:
addRecord(&fn,&ln,&s);
printf("> Record added. \n");
break;
case 3:
deleteRecord(&fn, &ln, &s);
printf("> Record deleted. \n");
break;
case 0:
return 0;
default:
return 0;
}
}
while(1);
}
// Print user menu
void printMenu(){
printf("\tMain Menu\t\n"
"============================\n"
" > Print records (press 1) \n"
" > Add a new record (press 2) \n"
" > Delete a record (press 3) \n"
"============================\n"
"Please select an option: ");
}
// Print all user records
void printRecords(char** fn, char** ln, double* s){
int i;
for(i=0;i<records;i++)
printf("(%d) First name: %s | Last name: %s | Score: %0.2lf \n",i+1,fn[i],ln[i],s[i]); // will start at the first item and go i amount in the index
}
void addRecord(char*** fn, char*** ln, double** s){
// gather value
char* fname = malloc(64);
char* lname = malloc(64);
double score;
records++;
printf("%d) ", (counter));
scanf("%s %s %lf",fname, lname, &score);
addString(fn, fname);
addString(ln, fname);
addDouble(s, score);
}
void addString(char*** strArray, char* str){
// realloc array one larger
*strArray = realloc(*strArray, (records) * sizeof(char*));
// set pointer equal
(*strArray)[records-1] = str;
}
void addDouble(double** dubArray, double dub){
// realloc array one larger
*dubArray = realloc(*dubArray, (records) * sizeof(double));
// set pointer equal
(*dubArray)[records-1] = dub;
}
void deleteRecord(char*** fn, char*** ln, double** s){
//This part gets the name
int i, j;
char *name = malloc(64);
printf("Please enter the last name of the record(s) you'd like to delete: ");
scanf("%s",name);
while(findName(*ln, name) != 0){
for(i = 0;i<records && strcmp(name,(*ln)[i]) != 0;i++);
records--;
//free((*ln)[i]);
//free((*fn)[i]);
for(i=i; i < records-1; i++){
(*ln)[i] = (*ln)[i+1];
(*fn)[i] = (*fn)[i+1];
(*s)[i] = (*s)[i+1];
}
removeString(fn);
removeString(ln);
removeDouble(s);
}
}
void removeString(char ***strArray){
*strArray = realloc(*strArray, (records) * sizeof(char*));
}
void removeDouble(double** dubArray){
*dubArray = realloc(*dubArray, (records) * sizeof(double));
}
// Finds how many instances of a last name are present
int findName(char** ln,char* n){
int i, counter=0;
for(i=0;i<records-1;i++){
if(strcmp(n,*(ln+i)) == 0){
counter++;
}
}
return counter;
}
我是 C 语言的初学者,我正在尝试以最简单的方式学习动态内存分配 - 我有一个管理学生记录的程序,但我有一些我一生都无法解决的问题即使在 googleing/Whosebuging 几个小时之后 -- 这是这个程序要完成的:
- 接收学生记录
- 添加和删除记录(这些命令不起作用)
- 对学生记录进行排序
- 从这些记录中找到一些额外的值
这是在 GDB 调试器中发现的导致此错误的原因(问题来自 addRecord 函数和 freeMemory 函数):
*** Error in `/home/a.out': realloc(): invalid next size:
0x0000000000c42060 ***
Aborted
并且当在 GDB 调试器之外使用 GCC 和 运行 编译时,它只会出现段错误。
只有当我在程序中执行这些选项时才会发生这种情况:
1) 添加一条记录
2) 删除记录
3) 添加一条记录(然后崩溃)
或
1) 添加一条记录
2) 添加一条记录(然后崩溃)
我不确定是什么原因造成的,我也不知道如何解决,谁能帮我指明正确的方向?我尝试在 freeMemory 函数中 realloc 成功后添加一个 free 但无济于事,这会导致程序在删除添加的记录时崩溃。
代码如下:
#include <stdio.h>
#include <stdlib.h>
// Declare functions:
void printMenu();
void printRecords(char** fn, char** ln, float* s);
void addRecord(char** fn, char** ln, float* s);
void deleteRecord(char** fn, char** ln, float* s);
int freeMemory(char** fn, char** ln, float* s, char* n, int matches);
int findName(char** ln,char* n);
static int records; // global records variable
int main(){
int i, j;
int choice;
int option = -1;
printf("WELCOME TO THE STUDENT RECORD MANAGER 100 V 1.0! \n");
printf("Please indicate the number of student records you want to enter (min 5, max 15): \n");
scanf("%d",&records);
if(records < 5 || records > 15){
printf("You must enter more than five and less than 15... terminating. \n");
return 0;
}
// Declare arrays
char** firstNames;
char** lastNames;
float* scores;
// Declare variables
char* search = malloc(64);
firstNames = malloc(records*sizeof(*firstNames));
lastNames = malloc(records*sizeof(*lastNames));
scores = malloc(records*sizeof(float));
printf("Please enter the records now (ex. firstName lastName score ENTER):\n");
// Gather Records
for(i = 0; i < records; i ++){
printf("%d ",i+1);
firstNames[i] = malloc(254 * sizeof(char));
lastNames[i] = malloc(254 * sizeof(char));
//scores[i] = malloc(sizeof(float));
scanf("%s %s %f",firstNames[i], lastNames[i], &scores[i]);
}
// Generate menu and do actions
do{
printMenu();
scanf("%d",&choice);
switch(choice){
case 1:
printRecords(firstNames, lastNames, scores);
break;
case 2:
addRecord(firstNames, lastNames, scores);
break;
case 3:
deleteRecord(firstNames, lastNames, scores);
break;
case 0:
return 0;
}
}
while(1);
return 0;
}
// Print user menu
void printMenu(){
printf("\tMain Menu\t\n"
"============================\n"
" > Print records (press 1) \n"
" > Add a new record (press 2) \n"
" > Delete a record (press 3) \n"
" > Exit the program (press 0)\n"
"============================\n"
"Please select an option: ");
}
// Print all user records
void printRecords(char** fn, char** ln, float* s){
int i;
printf("THERE ARE %d RECORDS \n",records);
for(i=0;i<records;i++)
printf("(%d) First name: %s | Last name: %s | Score: %0.2f \n",i,fn[i],ln[i],s[i]); // will start at the first item and go i amount in the index
}
// Add user record
void addRecord(char** fn, char**ln, float* s){
char** tempPtr;
float* tempFPtr;
printf("Please input the values that you'd like to add (ex. firstName lastName score ENTER): \n");
if(records+1 < 15){ // if the array is not larger than maximum value when we make it larger
// lets reallocate the arrays
tempPtr = realloc(fn, (records+1)*sizeof(*fn));
if(tempPtr){
printf("ALLOCATION successfully");
fn = tempPtr;
}
else{
printf("FAILED");
// Realloc Failed
}
tempPtr = realloc(ln, (records+1)*sizeof(*ln));
if(tempPtr){
printf("ALLOCATION successfully");
ln = tempPtr;
}
else{
printf("FAILED");
// Realloc Failed
}
/*tempFPtr = realloc(s, records+1*sizeof(float));
if(tempFPtr){
s = tempFPtr;
}*/
printf("There are now %d items.. \n", records);
fn[records] = malloc(64); // in the LAST value of all arrays
ln[records] = malloc(64);
scanf("%s %s %f",fn[records], ln[records], &s[records]);
printf("(%d) > ADDED -> First name: %s | Last name: %s | Score: %0.2f \n",records,fn[records],ln[records],s[records]);
int i;
records++; // increment by one
printf("There are now %d items.. \n", records);
printf(" > Record successfully added.\n");
}
else{
printf(" > You have hit the max amount of records allowed for this program (15).\n");
}
}
// Delete all instances of user record by (last Name)
void deleteRecord(char** fn, char**ln, float* s){
char* lastName = malloc(32 * sizeof(char*));
printf("What is the last name of the student you would like to delete? \n");
scanf("%s", lastName);
// searching for that record
int matches = findName(ln, lastName);
if(matches && records-matches > 4){ // this means it doesn't go below minimum 5
if(freeMemory(fn, ln, s, lastName, matches)){
printf(" > Record successfully deleted.\n");
free(lastName);
}
}
else{
printf(" > Either no matches were found or deleting this value would put the number of records at less than 5. \n");
}
}
// Extension of deleteRecord that does duplication to push 'delete' lastName to the end, then reallocates array to cut it off the end
int freeMemory(char** fn, char** ln, float* s, char* n, int matches){
int i,j;
/* LOGIC:
- REALLOCATE ARRAY BY X LESS SIZE AFTER PUSHING THE VALUES TO BE REMOVED TO THE END
- NEED TO DO THIS FOR THREE ARRAYS
- TO REMOVE:
- RUN THROUGH X AMOUNT OF TIMES PUSHING EACH SPECIFIC REMOVAL VALUE (IE) 1st found match
- TO THE END
SHIFT
- FOUND 1st MATCH
- MATCH = MATCH + 1
- MATCH + ! = MATCH + 2
- ETC UNTIL YOU HAVE A DUPLICATE AT THE END, THEN REALLOCATE BY 1 LESS
*/
char** tempPtr = NULL;
float* tempFPtr = NULL;
for(i=0;i<matches;i++){ // gonna go through as many times as matches
int match = 0;
// let's make sure the name isn't on the end of the array before we do all this junk
if(strcmp(n,*(ln+records-1)) == 0){
printf("FN");
tempPtr = realloc(fn, (records-1)*sizeof(*fn));
if(tempPtr){
fn = tempPtr;
printf("FN PASSED");
//free(fn[records]);
}
else{
// Realloc Failed
printf("FN FAILED");
}
printf("LN");
tempPtr = realloc(ln, (records-1)*sizeof(*ln));
if(tempPtr){
ln = tempPtr;
printf("LN PASSED");
//free(ln[records]);
}
else{
printf("LN FAILED");
// Realloc Failed
}
records--;
}
else{
// lets find the first match by going through each last name
for(j=0;j<records-1;j++){
// Lets find first match
if(strcmp(n,ln[j]) == 0){ // accessing index
// lets start copying
*(ln+j) = *(ln+j+1);
*(fn+j) = *(fn+j+1);
*(s+j) = *(s+j+1);
match = 1;
}
else if(match){
// already copied first val so lets start copying the rest until we get to the end.
*(ln+j) = *(ln+j+1);
*(fn+j) = *(fn+j+1);
*(s+j) = *(s+j+1);
}
}
printf("FN");
tempPtr = realloc(fn, (records-1)*sizeof(*fn));
if(tempPtr){
fn = tempPtr;
printf("FN PASSED");
//free(fn[records]);
}
else{
// Realloc Failed
printf("FN FAILED");
}
printf("LN");
tempPtr = realloc(ln, (records-1)*sizeof(*ln));
if(tempPtr){
ln = tempPtr;
printf("LN PASSED");
//free(ln[records]);
}
else{
printf("LN FAILED");
// Realloc Failed
}
/*tempFPtr = realloc(s, records-1*sizeof(float));
if(tempFPtr){
s = tempFPtr;
printf("S PASSED");
}
else{
printf("s FAILED ");
}*/
records--;
match = 0;
}
}
return 1;
}
// Finds how many instances of a last name are present
int findName(char** ln,char* n){
int i, counter=0;
for(i=0;i<records-1;i++){
if(strcmp(n,*(ln+i)) == 0){
counter++;
}
}
return counter;
}
错误似乎在您的函数中 addRecord
。你有表达式
tempPtr = safe_trim(ln, records+1*sizeof(*ln));
由于 C operator precedence,它给出了 records + (sizeof (*ln))
的大小。乘法先于加法。该行应更改为:
tempPtr = safe_trim(ln, (records + 1) * sizeof(*ln));
还因为 safe_trim
始终 return 一个有效的指针,无论是原始指针还是调整后的指针,此检查
tempPtr = safe_trim(fn, records+1*sizeof(*fn));
if(tempPtr){
printf("ALLOCATION successfully");
fn = tempPtr;
}
else{
printf("FAILED");
// Realloc Failed
}
永远不会遵循 else
分支并且不会处理分配失败。将对 safe_trim
的调用替换为 realloc
应该不会对程序产生任何影响,除非允许检测分配失败。
我已经解决了问题。这是因为我没有使用三重指针,它没有寻址原始变量。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void printMenu();
void printRecords(char** fn, char** ln, double* s);
void addRecord(char ***fn, char ***ln, double **s);
void addString(char ***strArray, char* str);
void addDouble(double** dubArray, double dub);
void deleteRecord(char*** fn, char*** ln, double** s);
void removeString(char ***strArray);
void removeDouble(double** dubArray);
int findName(char** ln,char* n);
int records;
int counter;
int main(){
records = 0;
counter = 1;
int initRecords = 0;
int choice,i;
char **fn; // first Names
char **ln; // last Names
double *s; // score
printf("= =\n"
"Please enter how many value"
"s you would like to initall"
"y enter [min 5, max 15]: ");
scanf("%d", &initRecords);
if(initRecords < 5 || initRecords > 15)
return 0;
// allocate memory
fn = malloc(0); // will reallocate later
ln = malloc(0);
s = malloc(0);
printf("Please enter the value (firstName lastName score ENTER): \n");
for(i = 0;i<(initRecords);i++){
addRecord(&fn, &ln, &s);
counter++;
}
printf("Records added... \n");
do{
printMenu();
scanf("%d",&choice);
switch(choice){
case 1:
printRecords(fn, ln, s);
break;
case 2:
addRecord(&fn,&ln,&s);
printf("> Record added. \n");
break;
case 3:
deleteRecord(&fn, &ln, &s);
printf("> Record deleted. \n");
break;
case 0:
return 0;
default:
return 0;
}
}
while(1);
}
// Print user menu
void printMenu(){
printf("\tMain Menu\t\n"
"============================\n"
" > Print records (press 1) \n"
" > Add a new record (press 2) \n"
" > Delete a record (press 3) \n"
"============================\n"
"Please select an option: ");
}
// Print all user records
void printRecords(char** fn, char** ln, double* s){
int i;
for(i=0;i<records;i++)
printf("(%d) First name: %s | Last name: %s | Score: %0.2lf \n",i+1,fn[i],ln[i],s[i]); // will start at the first item and go i amount in the index
}
void addRecord(char*** fn, char*** ln, double** s){
// gather value
char* fname = malloc(64);
char* lname = malloc(64);
double score;
records++;
printf("%d) ", (counter));
scanf("%s %s %lf",fname, lname, &score);
addString(fn, fname);
addString(ln, fname);
addDouble(s, score);
}
void addString(char*** strArray, char* str){
// realloc array one larger
*strArray = realloc(*strArray, (records) * sizeof(char*));
// set pointer equal
(*strArray)[records-1] = str;
}
void addDouble(double** dubArray, double dub){
// realloc array one larger
*dubArray = realloc(*dubArray, (records) * sizeof(double));
// set pointer equal
(*dubArray)[records-1] = dub;
}
void deleteRecord(char*** fn, char*** ln, double** s){
//This part gets the name
int i, j;
char *name = malloc(64);
printf("Please enter the last name of the record(s) you'd like to delete: ");
scanf("%s",name);
while(findName(*ln, name) != 0){
for(i = 0;i<records && strcmp(name,(*ln)[i]) != 0;i++);
records--;
//free((*ln)[i]);
//free((*fn)[i]);
for(i=i; i < records-1; i++){
(*ln)[i] = (*ln)[i+1];
(*fn)[i] = (*fn)[i+1];
(*s)[i] = (*s)[i+1];
}
removeString(fn);
removeString(ln);
removeDouble(s);
}
}
void removeString(char ***strArray){
*strArray = realloc(*strArray, (records) * sizeof(char*));
}
void removeDouble(double** dubArray){
*dubArray = realloc(*dubArray, (records) * sizeof(double));
}
// Finds how many instances of a last name are present
int findName(char** ln,char* n){
int i, counter=0;
for(i=0;i<records-1;i++){
if(strcmp(n,*(ln+i)) == 0){
counter++;
}
}
return counter;
}