2017-04-03 7 views
0

私は学生の追加/変更と削除ができるはずの学生のデータベースプログラムを作成しようとしています。私は追加機能を動作させることができましたし、変更機能も削除機能は私にいくつかの問題をもたらします。私のコードは、データベースから生徒を削除しようとしたときにクラッシュするようですが、誰かが問題のある場所を教えてくれますか?ここでStructsの動的配列、要素を削除する

は私のコードです:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

/* TODO: Avoid global variables. */ 

struct student { 
    char name[60]; 
    long long personalNumber; 
    char gender[6]; 
    char studyProgram[60]; 
    char email[30]; 
    int age; 
}; 

struct student *pointer = NULL; 
int numberofstudents = 0; 

void modify() 
{ 
    long long persnr; 
    long long comp; 
    int match = 0; 
    printf("Please enter the personal number that you wish to modify: \n"); 
    scanf("%lld", &persnr); 
    getchar(); 

    for(int i = 0; i <= numberofstudents; i++) 
    { 
     comp = ((pointer+i)->personalNumber); 
     printf("%lld\n", ((pointer+i)->personalNumber)); 
     printf("%lld\n", comp); 


     printf("Inne"); 
     if (pointer[i].personalNumber == persnr && match == 0) 
     { 
      printf("Enter name, personalnumber, gender, studyprogram, email and age in this order\n"); 
      scanf("%s%lld%s%s%s%d", (pointer+i)->name, &(pointer+i)->personalNumber, (pointer+i)->gender, (pointer+i)->studyProgram, (pointer+i)->email, &(pointer+i)->age); 
      match = 1; 
      getchar(); 
     } 
     if (match == 0) 
     { 
      printf("Could not find person"); 
     } 

    } 
} 


void deletestudent() 
{ 
    long long persnr; 
    long long comp; 
    int match = 0; 
    printf("Please enter the personal number that you wish to delete: \n"); 
    scanf("%lld", &persnr); 
    getchar(); 

    struct student *temporary = malloc((numberofstudents - 1) * sizeof(struct student)); 

    for(int i = 0; i <= numberofstudents; i++) 
    { 
     if (pointer[i].personalNumber == persnr && match == 0) 
     { 
      match = 1; 
     } 
     else if (match == 1){ 
      temporary[i-1] = pointer[i]; 
     } 
     else 
     { 
      temporary[i] = pointer[i]; 
     } 

     if (match == 0) 
     { 
      printf("Could not find person"); 
     } 

    } 
    free(pointer); 
    pointer = temporary; 

    } 



void add(){ 

     if (numberofstudents > 0) 
     { 
      pointer = (struct student*) realloc(pointer, (numberofstudents+1) * sizeof(struct student)); 

      printf("Lyckades allokeringen!\n\n"); 
     } 

     printf("Enter name, personalnumber, gender, studyprogram, email and age in this order\n"); 
     scanf("%s%lld%s%s%s%d", (pointer+numberofstudents)->name, &(pointer+numberofstudents)->personalNumber, (pointer+numberofstudents)->gender, (pointer+numberofstudents)->studyProgram, (pointer+numberofstudents)->email, &(pointer+numberofstudents)->age); 
     getchar(); 
     printf("Visar data:\n"); 

     for(int i = 0; i <= numberofstudents; ++i) 
     { 
      printf("%s\t%lld\t%s\t%s\t%s\t%d\n", (pointer+i)->name, (pointer+i)->personalNumber, (pointer+i)->gender, (pointer+i)->studyProgram, (pointer+i)->email, (pointer+i)->age); 
     } 
     numberofstudents = numberofstudents+1; 
    } 

int main(void) 
{ 
    pointer = (struct student*) malloc(2 * sizeof(struct student)); 

    if (pointer == NULL) 
{ 
    printf("pointer NULL"); 
    exit(1); 
} 

    int run = 1; 
    int choice; 

    while (run == 1) 
    { 
     printf("Please enter an option listed below\n1.ADD\n2.Modify\n3.Delete\n4.Search\n5.Save\n6.Load\n7.Exit"); 
     scanf("%d", &choice); 
     getchar(); 

     switch(choice) { 

    case 1 : 
     add(); 
     break; 

    case 2 : 
     modify(); 
     break; 
    case 3 : 
     deletestudent(); 


    case 7 : 
     exit(0); 
     break; 

    default : 

     break; 
} 

    } 


    return 0; 
} 
+1

'numberofstudents'は配列内の要素の数、または配列内のトップインデックスですか?なぜなら、それが最初のものであれば、あなたのすべてのループは終わりを越えて行き、あなたは境界から外れてインデックスを作成するときに*未定義の振る舞い*を持つからです。 –

+0

'deletestudent()'の 'persnr'が存在しない場合、' numberofstudents'要素を 'temporary'にコピーします(実際には@some programmer dudeのコメントを参照してください)が、配列には-1要素が割り当てられます。また、 'numberofstudents'を減らさないでください –

+0

" female "のように5文字以上のジェンダーを入力すると、問題(未定義の動作)が発生します。 (個人番号に整数型を使うのは疑問です;実数よりも数字の列(数字)が多いです。) – molbdnilo

答えて

0

コメントで述べたように、この:

for(int i = 0; i <= numberofstudents; i++) 

は巨大な警告サインです。 Cでは、numberofstudentsが配列の実際の長さであると仮定すると、そのようなループは通常、i < numberofstudentsになります。

<ではなく<=を使用すると、ループが一歩進んでしまい、配列の外側にインデックスが設定され、未定義の動作が発生します。

ヒープ割り当てメモリの外側に書き込んでからfree()にしようとすると、ヒープアロケータのデータ構造を踏んでいる可能性があるため、クラッシュを引き起こす良い方法です(実際には、未定義の動作を取得し、何かが起こる可能性があります)。

関連する問題