2012-10-05 2 views
0

저는 C로 시작해서 막후에서 무슨 일이 벌어지고 있는지에 대해서는 거의 알려지지 않았습니다. 필자는 데이터 구조 클래스를 위해 그것을 배우면서 조금 더 어렵게 만듭니다.포인터로 C로 구조체 정렬하기

업데이트 : 프로그램을 제거한 후 메모리로 시작하여 다시 시작합니다. 나는 내가이 malloc에 ​​오류가의 할당 및 할당 해제 기능 얻고있다 : Q1 (9882)의 malloc : *에 대한 오류 객체 0x7fff59daec08 : 포인터 * 디버깅 malloc_error_break에 중단 점을 설정 할당되지 않은 해제되지

갱신 2는 여기에 여전히 뭔가를 놓치고, 내 개정 된 코드입니다, 내 printf와 문장의 몇 게재되지 않습니다

#include <stdio.h> 
#include<stdlib.h> 
#include<math.h> 
#include<assert.h> 

static int size = 10; 

struct student{ 
    int id; 
    int score; 
}; 

struct student* allocate(){ 
    /*Allocate memory for ten students*/ 
    struct student *s = malloc(size*(sizeof(struct student))); 
    assert(s != 0); 
    /*return the pointer*/ 
    return s; 
} 

void generate(struct student* students){ 
    /*Generate random ID and scores for ten students, ID being between 1 and 10, scores between 0 and 100*/ 
    srand((unsigned int)time(NULL)); 
    int id[size]; 
    int y; 

    for (int i = 0; i < size; i++){ 
     y = rand() % size + 1; 
     while(dupe(id, i, y)){ 
      y = rand() % size + 1; 
     } 
     id[i] = y; 
    } 

    for (int j = 0; j < size; j++){ 
     (students + j)->id = id[j]; 
     (students + j)->score = rand() % 101; 
     printf("ID: %d\tScore: %d\n", (students + j)->id, (students + j)->score); 
    } 
} 

int dupe(int id[], int size1, int i){ 
    for (int x = 0; x < size1; x++){ 
     if(id[x] == i) 
      return 1; 
    } 
    return 0; 
} 

void output(struct student* students){ 
    /*Output information about the ten students in the format: 
       ID1 Score1 
       ID2 score2 
       ID3 score3 
       ... 
       ID10 score10*/ 
    sort(&students); 
    for(int x = 0; x < size; x++){ 
     printf("ID: %d\tScore: %d\n", (students + x)->id, (students + x)->score); //print stmt not showing 
    } 
} 

void sort(struct student* students){ 
    struct student *sd = allocate(); 

    struct student *stud; 

    for(int i = 0; i < size; i++){ 
     stud = &students[i]; 
     sd[stud->id] = *stud; 
    } 
    for(int x = 0; x < size; x++){ 
     printf("ID: %d\tScore: %d\n", (sd + x)->id, (sd + x)->score); //print stmt not showing 
    } 
    students = &sd; 
    deallocate(sd); 
} 

void summary(struct student* students){ 
    /*Compute and print the minimum, maximum and average scores of the ten students*/ 

} 

void deallocate(struct student* stud){ 
    /*Deallocate memory from stud*/ 
    free(stud); 
} 

int main(){ 
    struct student* stud = NULL; 
    char c[] = "------------------------------\n"; 
    /*call allocate*/ 
    stud = allocate(); 
    /*call generate*/ 
    generate(&stud); 
    /*call output*/ 
    printf("%s", c); 
    output(&stud); 
    /*call summary*/ 

    /*call deallocate*/ 
    deallocate(stud); 

    return 0; 
} 
+1

숙제 태그 [사용되지]입니다 (http://meta.stackexchange.com/questions/147100/the-homework-tag-is-now-officially-deprecated). – chris

+0

답변을 무효화하므로 코드를 수정하지 마십시오. 새 질문을 제출하십시오. 나는 당신이 그걸 보았다는 것을 알았습니다 ... 당신의 새로운 질문에 대한 광범위한 답변을보십시오. 그리고 정답을 받아들이면, 아무도 시간을들이는 데 방해가 될 것입니다. –

답변

4
students = &students[x]; 

students 점은, 루프를 통해 다음 번에 있도록하지 처음부터 거기에서 offseting 할 곳이 변경됩니다. 즉, originalstudents[0], originalstudents[1], originalstudents[1+2], originalstudents[1+2+3] 등이 있습니다. sd과 동일한 문제가 있습니다.

대신 당신은 무엇을 위해 SD되고, 또한

struct student* st = &students[x]; 
printf("id = %d\tscore = %d\n", st->id, st->score); 
etc 

같은 다른 변수를 사용하려면? 명백한 이유가 없으므로 일부 공간을 할당하고 학생을 SD로 복사하는 것 같습니다. 할당 된 공간은 저장되거나 반환되지 않습니다 ... 메모리 누수입니다. 오, 잠깐, 알다시피 ... sd의 학생들을 이드의 순서대로 재주문합니다. 따라서 작업이 끝나면 그냥 기억을 풀어 줘야합니다. 하지만 학생과 sd 모두 배열의 요소보다 배열에 다른 포인터가 필요합니다. 여러 가지 명명 규칙을 사용할 수 있지만 일관된 규칙을 사용하는 것이 좋습니다. 예를 들면 : 당신이 당신의 학생 데이터를 통해 모든 짓밟고되도록

void output(struct Student* students){ 
    struct Student *idstudents = allocate(); /* sorted by id */ 
    if (!idstudents) 
     /* handle allocation error */; 

    for (int x = 0; x < 10; x++){ 
     struct Student* student = &students[x]; 
     printf("id = %d\tscore = %d\n", student->id, student->score); 
     struct Student* idstudent = &idstudents[student->id]; 
     *idstudent = *student; /* copy all fields at once */ 
     printf("id = %d\tscore = %d\n", idstudent->id, idstudent->score);/* pointless here, since we just printed the same info via student */ 
    } 

    for (int x = 0; x < 10; x++){ 
     struct Student* idstudent = &idstudents[x]; 
     printf("id = %d\tscore = %d\n", idstudent->id, idstudent->score); 
    } 
    deallocate(idstudents); 
} 
+0

위의 내용을 편집하여 malloc을 보여주었습니다. 프로그램에서 벗어나는 것 같습니다. 나는 심지어 내가 나의 종류를 고칠 수 있기 전에 그것을 다루는 방법이 명확하지 않다. – hobbes131

0

이 문

students = &students[x]; 

변형 된을 인수. 학생들이 지적한 것을 분실했습니다. 이는 struct student []의 시작입니다.

이 문장을 제거하고 다시 프로그램을 실행 해보십시오.

다른 오류가 있지만이 문제는 풀리지 않습니다.

포인터가 어렵습니다.

+0

문을 제거하면 루프가 항상 동일한 항목에서 작동합니다. 그리고 포인터에 관해 특별히 어려운 것은 없습니다. –

1

귀하의 output() 기능은 포인터를 오용된다. (즉, 당신이 그들을 사용하는 방법이기 때문에, ID를 배열 인덱스입니다 가정) 같은 것을보십시오 :

당신이 학생의 수를 하드 코딩했기 때문에
struct student* allocate() 
{ 
    /*Allocate memory for ten students*/ 
    struct student *s = malloc(10 * sizeof(struct student)); 
    assert(s != NULL); 
    /*return the pointer*/ 
    return s; 
} 

void deallocate(struct student* stud) 
{ 
    /*Deallocate memory from stud*/ 
    free(stud); 
} 

int main() 
{ 
    struct student* stud = NULL; 

    /*call allocate*/ 
    stud = allocate(); 

    /*call generate*/ 

    /*call output*/ 
    output(stud); 

    /*call summary*/ 

    /*call deallocate*/ 
    deallocate(stud); 

    return 0; 
} 

void output(struct student* students) 
{ 
    /*allocate array for sorting*/ 
    struct student *sd = allocate(); 

    struct student *stud; 

    /*make copy of students in sorted order*/ 
    for (int x = 0; x < 10; ++x) 
    { 
     stud = &students[x]; 
     printf("id = %d\tscore = %d\n", stud->id, stud->score); 
     sd[stud->id] = *stud; 
    } 

    /*output sorted students*/ 
    for (int x = 0; x < 10; ++x) 
    { 
     stud = &sd[x]; 
     printf("id = %d\tscore = %d\n", stud->id, stud->score); 
    } 

    /*deallocate array for sorting*/ 
    deallocate(sd); 
} 

, 동적으로 새로운 할당에 대한 필요성을 제거 할 수 output() 학생들의 배열, 그리고 당신이 이미 원래의 배열에있는 포인터 분류 :

void output(struct student* students) 
{ 
    /*array for sorting*/ 
    struct student* sd[10]; 

    struct student *stud; 

    /*sort students*/ 
    for (int x = 0; x < 10; ++x) 
    { 
     stud = &students[x]; 
     printf("id = %d\tscore = %d\n", stud->id, stud->score); 
     sd[stud->id] = stud; 
    } 

    /*output sorted students*/ 
    for (int x = 0; x < 10; ++x) 
    { 
     stud = sd[x]; 
     printf("id = %d\tscore = %d\n", stud->id, stud->score); 
    } 
} 

업데이트을 : 지금 당신은 당신의 코드를 더 보여, 당신은 여전히 ​​포인터 몇 가지 큰 실수를하고 있습니다 . 코드를 표시 한 것처럼 컴파일하지 않아야합니다.대신이 시도 :

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#include <assert.h> 

static const int numStudents = 10; 

struct student 
{ 
    int id; 
    int score; 
}; 

struct student* allocate() 
{ 
    /*Allocate memory for ten students*/ 
    struct student *s = malloc(numStudents * sizeof(struct student)); 
    assert(s != 0); 
    /*return the pointer*/ 
    return s; 
} 

void generate(struct student* students) 
{ 
    /*Generate random ID and scores for ten students, ID being between 1 and 10, scores between 0 and 100*/ 
    int id[numStudents]; 
    int y; 
    struct student* stud; 

    for (int i = 0; i < numStudents; i++) 
    { 
     do 
     { 
      y = rand() % size + 1; 
     } 
     while (dupe(id, i, y) != 0); 
     id[i] = y; 
    } 

    for (int j = 0; j < numStudents; j++) 
    { 
     stud = &students[j]; 
     stud->id = id[j]; 
     stud->score = rand() % 101; 
    } 
} 

int dupe(int id[], int size, int i) 
{ 
    for (int x = 0; x < size; x++) 
    { 
     if (id[x] == i) 
      return 1; 
    } 
    return 0; 
} 

void output(struct student* students) 
{ 
    /*Output information about the students in the format: 
       ID1 Score1 
       ID2 score2 
       ID3 score3 
       ... 
       ID10 score10*/ 

    struct student* stud; 

    for(int x = 0; x < numStudents; x++) 
    { 
     stud = &students[x]; 
     printf("ID: %d\tScore: %d\n", stud->id, stud->score); 
    } 
} 

void sort(struct student* students) 
{ 
    struct student *sd = allocate(); 
    struct student *stud; 

    for(int i = 0; i < numStudents; i++) 
    { 
     stud = &students[i]; 
     sd[stud->id - 1] = *stud; 
    } 

    for(int x = 0; x < numStudents; x++) 
    { 
     stud = &sd[x]; 
     students[x] = *stud; 
    } 

    deallocate(sd); 
} 

void summary(struct student* students) 
{ 
    /*Compute and print the minimum, maximum and average scores of the ten students*/ 
} 

void deallocate(struct student* stud) 
{ 
    /*Deallocate memory from stud*/ 
    free(stud); 
} 

int main() 
{ 
    /*seed random number generator*/ 
    srand(time(NULL)); 

    struct student* stud = NULL; 
    const char* c = "------------------------------\n"; 

    /*allocate students and generate info*/ 
    stud = allocate(); 
    generate(stud); 
    output(stud); 

    printf("%s", c); 

    /*sort students*/ 
    sort(students); 
    output(stud); 

    printf("%s", c); 

    /*display summary*/ 
    summary(stud); 

    /*deallocate students*/ 
    deallocate(stud); 

    return 0; 
} 
+0

이상한 출력 오류가 발생하여 파일을 다시 가져 오려고했는데 모든 것을 잃어 버렸습니다. 적어도 나는 그것의 약간을 여기에서 베꼈다! 할당 및 게시를 게시하면 malloc 오류가 발생합니다. – hobbes131

+0

'allocate()'함수가 잘못된 메모리 주소를 반환하고 있습니다. 그것은 로컬's' 변수 자체의 스택 주소를 리턴하지만 변수가 가리키는 힙 주소를 반환해야합니다. 이것은 malloc()이 반환 한 메모리 주소입니다. –

+0

아 하! 고맙습니다! – hobbes131