2017-12-10 13 views
-1

구조체를 배우려고하고 있는데 충돌하는 프로그램이 있습니다. 이유를 이해할 수 없습니다. 컴파일러는 구조체 배열의 요소에 액세스하려고 할 때 잘못된 액세스 예외를 throw합니다.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] (http://gcc.gnu.org/)가있는'g ++ -Wall -Wextra -g ...)로 컴파일하십시오. 코드를 개선하여 경고가 표시되지 않도록하십시오. ** 디버거 ** (예 :'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'이므로 배열 할당시 - 배열에는 하나의 'Student'만 포함되며 배열의 두 번째 요소에 액세스하려고하면 할당되지 않은 메모리의 참조가 없어서 정의되지 않은 동작이 호출됩니다 . –

답변

1

students 포인터의 초기화는 main의 실행 전에 이루어집니다. 그때까지 n을 읽지 않았을 것입니다. 따라서 코드가 students 배열에 1 학생에 대한 메모리 할당 끝납니다. 당신의 main

코드는 정말 사실이 아니다 동안 students 배열 size (또는 n의 현재 값)을 보유 할 수 있다고 가정합니다. 따라서 코드는 정의되지 않은 동작을 일으키는 알려지지 않은 위치에 액세스하게됩니다 (거의 세그먼테이션 오류가 발생 함).

n에 대한 입력을 수행 한 후 어레이의 메모리를 할당하는 것이 수정되었습니다.

0

분명히 학생의 한 크기 만 할당하면서 배열의 두 번째 학생을 액세스하려고하면 프로그램이 충돌했습니다. 배열의 메모리는 "n = size"코드 뒤에 할당해야하지만, 전에는 메인 입구의 상단에서 수행 한 것이 목적에 절대적으로 부합하지 않습니다.