2017-12-10 21 views
-1

構造体を学習しようとしていて、私のプログラムがクラッシュしています。構造体配列の要素にアクセスしようとすると、コンパイラは不正なアクセス例外をスローします。C++:構造体配列の要素にアクセスするとプログラムがクラッシュします

は、ここでは、コードです:

#include <iostream> 
#include <fstream> 

FILE *input; 

int n=1; 
struct Student { 
    string name; 
    string city; 
    int grades[4]; 
}; 
Student *students = new Student[n]; 

int main(int argc, const char * argv[]) { 

input = fopen("input.txt", "r"); 
if(input==NULL) { 
    cout<<"\nCan't open file input.txt"; 
    return; 
} 

int size; 
if(fscanf(input, "Size%d\n\n",&size)<=0) { 
    cout<<"\nAn error occurred."; 
    return; 
} 
n=size; 
cout<<"\nThe size is "<<n; 
for(int i=0;i<n-1;i++) { 
    Student newStud; 
    char name[255]; 
    char city[255]; 
    fscanf(input, "\n%s\n%s\n%d;%d;%d;%d;",name,city,&newStud.grades[0],&newStud.grades[1],&newStud.grades[2],&newStud.grades[3]); 
    newStud.fullName = name; 
    newStud.city = city; 
    cout<<"\nAdding student at "<<i; 
    students[i]=newStud; 
    cout<<"\nAdded successfully"; 
} 
fclose(input); 

cout<<"\nLoad complete!"; 
} 

INPUT.TXT:

Size5 

Bob 
NY 
10;10;10;10; 
Rick 
SF 
6;6;6;6; 
John 
NY 
2;3;2;5; 
Jack 
NY 
5;5;5;4; 

コンソール出力:

The size is 5 
Adding student at 0 
Added successfully 
Adding student at 1 
+0

すべての警告とデバッグ情報([gcc -Wall -Wextra -g'と[GCC](http://gcc.gnu.org/)など)でコンパイルしてください。警告を表示しないようにコードを改善する。 **デバッガ**(例: 'gdb')を使用して、プログラム内で何が起こっているのかを理解してください。 –

+1

緊急にお読みください:https://stackoverflow.com/questions/46991224/are-there-any-valid-use-cases-to-use-new-and-delete-raw-pointers-or-c-style-arr – user0042

+2

配列の割り当て時に 'n'が' 1'であるため、配列には1つの 'Student'しか含まれておらず、配列の2番目の要素にアクセスしようとすると、割り当てられていないメモリの逆参照。 –

答えて

1

studentsポインタの初期化はmainの実行前に行われます。それまでにnを読んでいないでしょう。したがって、あなたのコードはstudents配列内の1人の学生のためにメモリを割り当てることになります。あなたmain

コードはそれが本当にそうではないながらstudentsアレイsize(又はnの現在の値)を保持することが可能であることを前提としています。したがって、コードは未定義の動作を引き起こす未知の場所へのアクセスを終了させます(ほとんど常にセグメンテーションフォルトが発生します)。

nの入力が行われた後で、アレイのメモリを割り当てます。

0

明らかに、あなたがそれのために学生の1つのサイズを割り当てただけで、配列の2番目の学生にアクセスしようとすると、プログラムがクラッシュしました。あなたは、コード "n = size"の後に配列のメモリを割り当てなければなりませんが、あなたがメインエントランスの先頭で行ったことはあなたの目的には絶対に不合理です。

関連する問題