2017-04-05 1 views
0

다음 코드는 작동하지만 메모리 누수가 발생합니다. 프로그램이 연결된 목록과 동적 메모리 기능을 사용하고 있습니다. 프로그램은 명령 행 인수로서 .txt 파일을 제외합니다.내 C 프로그램에서 메모리 누수가

예제 파일 :

제이콥 밀러 832,323,244 21
톰 대런 8,931,701,830 19
폴 미첼 여기 329,797,231 20
Valgrind의

의 출력
==5742== HEAP SUMMARY: 
==5742==  in use at exit: 324 bytes in 9 blocks 
==5742== total heap usage: 11 allocs, 2 frees, 908 bytes allocated 
==5742== 
==5742== 52 bytes in 1 blocks are definitely lost in loss record 2 of 4 
==5742== at 0x4A0610C: malloc (vg_replace_malloc.c:195) 
==5742== by 0x400A2C: student_record_allocate (new.c:106) 
==5742== by 0x4007EB: main (new.c:46) 
==5742== 
==5742== 272 (16 direct, 256 indirect) bytes in 1 blocks are definitely lost in loss record 4 of 4 
==5742== at 0x4A0610C: malloc (vg_replace_malloc.c:195) 
==5742== by 0x400A1E: student_record_allocate (new.c:104) 
==5742== by 0x4008D1: parseFile (new.c:74) 
==5742== by 0x400803: main (new.c:47) 
==5742== 
==5742== LEAK SUMMARY: 
==5742== definitely lost: 68 bytes in 2 blocks 
==5742== indirectly lost: 256 bytes in 7 blocks 
==5742==  possibly lost: 0 bytes in 0 blocks 
==5742== still reachable: 0 bytes in 0 blocks 
==5742==   suppressed: 0 bytes in 0 blocks 
==5742== 
==5742== For counts of detected and suppressed errors, rerun with: -v 
==5742== ERROR SUMMARY: 66 errors from 21 contexts (suppressed: 4 from 4) 

여기에 코드 스 니펫에 문제가 있습니다.

void parseFile(char* filename, struct student_record_node** head) 
    { 
    FILE *fp; 
    student_record_node *sn; 

    fp = fopen(filename, "r"); 
    if (!fp) { 
     fprintf(stderr, "Can't Open file %s\n", filename); 
     exit(EXIT_FAILURE); 
    } 

    while(!feof(fp)) { 
     sn = student_record_allocate(); 

     fscanf(fp, "%20s", sn->record_->first_name_); 
     fscanf(fp, "%20s", sn->record_->last_name_); 
     fscanf(fp, "%d", &(sn->record_->student_id_)); 
     fscanf(fp, "%d", &(sn->record_->student_age_)); 

     appendNode(*head, sn); 
    } 

    fclose(fp); 
    } 

    void printNode(struct student_record_node* node) 
    { 
     printf("\nstruct student_record_node:\n"); 
     if (node) { 
     printf("\tstudent first name: %s\n",node->record_->first_name_); 
     printf("\tstudent second name: %s\n",node->record_->last_name_); 
     printf("\tstudent id: %d\n", node->record_->student_id_); 
     printf("\tstudent age: %d", node->record_->student_age_); 

    } 
    } 

    struct student_record_node* student_record_allocate() 
    { 
    student_record_node *newNode=NULL; 
    student_record *newRecord=NULL; 

    newNode = (student_record_node *)malloc(sizeof(student_record_node)); 
    newRecord = (student_record *)malloc(sizeof(student_record)); 
    newNode->record_ = newRecord; 
    newNode->next_ = NULL; 

    return newNode; 
    free(newNode->record_); 
    }  

    { 
     free(node->record_); 
    free(node->next_); 

    } 

나는이 방법 여기

void freeNodeList(struct student_record_node* head) 
    { 
    student_record_node *tmp; 
    while(tmp != NULL) { 
    tmp=head; 
    head=head->next_; 
    free(tmp); 
    } 
    head=NULL; 
    } 

을 통해 위 확보하고 나의 전체 코드입니다

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

    struct student_record 
    { 
    int student_id_; 
    int student_age_; 
    char first_name_[21]; 
    char last_name_[21]; 
    }s; 

    struct student_record_node 
    {  
    struct student_record* record_; 
    struct student_record_node* next_; 
    }; 
    typedef struct student_record student_record; 
    typedef struct student_record_node student_record_node; 

    void parseFile(char* filename, struct student_record_node** head); 
    void printNode(struct student_record_node* node); 
    struct student_record_node* student_record_allocate(); 
    void student_record_node_deallocate(struct student_record_node* node); 
    void sortByAge(struct student_record_node** recordsHead); 
    void sortById(struct student_record_node** recordsHead); 
    void swap(struct student_record_node** node1, struct student_record_node** node2); 
    void freeNodeList(struct student_record_node* head); 
    void appendNode(struct student_record_node* head, struct student_record_node* newNode); 
    void printNodeList(struct student_record_node* head); 
    int main(int argc, char **argv) 
    { 
    student_record_node *head; 
    if (argc != 2) { 
     fprintf(stderr, "Error: expected input file"); 
     exit(EXIT_FAILURE); 
    } 
    /* student_record *newRecord=NULL; 
    recordsHead->record_ = newRecord; 
    recordsHead->next_ = NULL; 
    */ 
    head = student_record_allocate(); 
    parseFile(argv[1], &head); 
    printf("Before sorting..."); 
    printNodeList(head); 
    printf("Sorting by age..."); 
    sortByAge(&head); 
    printNodeList(head); 
    printf("Sorting by id..."); 
    sortById(&head); 
    printNodeList(head); 
    freeNodeList(head); 
    free(head); 

    return 0; 
    } 

    void parseFile(char* filename, struct student_record_node** head) 
    { 
    FILE *fp; 
    student_record_node *sn; 

    fp = fopen(filename, "r"); 
    if (!fp) { 
     fprintf(stderr, "Can't Open file %s\n", filename); 
     exit(EXIT_FAILURE); 
    } 

    while(!feof(fp)) { 
     sn = student_record_allocate(); 

     fscanf(fp, "%20s", sn->record_->first_name_); 
     fscanf(fp, "%20s", sn->record_->last_name_); 
     fscanf(fp, "%d", &(sn->record_->student_id_)); 
     fscanf(fp, "%d", &(sn->record_->student_age_)); 

     appendNode(*head, sn); 
    } 

    fclose(fp); 
    } 

    void printNode(struct student_record_node* node) 
    { 
     printf("\nstruct student_record_node:\n"); 
     if (node) { 
     printf("\tstudent first name: %s\n",node->record_->first_name_); 
     printf("\tstudent second name: %s\n",node->record_->last_name_); 
     printf("\tstudent id: %d\n", node->record_->student_id_); 
     printf("\tstudent age: %d", node->record_->student_age_); 

    } 
    } 

    struct student_record_node* student_record_allocate() 
    { 
    student_record_node *newNode=NULL; 
    student_record *newRecord=NULL; 

    newNode = (student_record_node *)malloc(sizeof(student_record_node)); 
    newRecord = (student_record *)malloc(sizeof(student_record)); 
    newNode->record_ = newRecord; 
    newNode->next_ = NULL; 

    return newNode; 
    free(newNode->record_); 
    }  

    { 
     free(node->record_); 
    free(node->next_); 

    } 

    void sortByAge(struct student_record_node **recordsHead) 
    { 
    int swapped, i; 
    struct student_record_node *ptr1; 
    struct student_record_node *lptr = NULL; 

    do 
    { 
     swapped = 0; 
     ptr1 = *recordsHead; 

     while (ptr1->next_ != lptr) 
     { 
      if (ptr1->record_->student_age_ > ptr1->next_->record_->student_age_) 
      { 
       swap(&ptr1, &ptr1->next_); 
       swapped = 1; 
      } 
      ptr1 = ptr1->next_; 
     } 
     lptr = ptr1; 
    } 
    while (swapped); 
    } 

    void sortById(struct student_record_node** recordsHead) 
    { 
    int swapped, i; 
    struct student_record_node *ptr1; 
    struct student_record_node *lptr = NULL; 

    do 
    { 
     swapped = 0; 
     ptr1 = *recordsHead; 

     while (ptr1->next_ != lptr) 
     { 
      if (ptr1->record_->student_id_ > ptr1->next_->record_->student_id_) 
      { 
       swap(&ptr1, &ptr1->next_); 
       swapped = 1; 
      } 
      ptr1 = ptr1->next_; 
     } 
     lptr = ptr1; 
    } 
    while (swapped); 
    } 

    void swap(struct student_record_node** node1, struct student_record_node** node2) 
    { 
    student_record_node *tmp, *n1, *n2; 

    n1 = *node1; 
    n2 = *node2; 
    tmp->record_= n1->record_; 
    n1->record_= n2->record_; 
    n2->record_ = tmp->record_; 

    } 

    void freeNodeList(struct student_record_node* head) 
    { 
    student_record_node *tmp; 
    while(tmp != NULL) { 
    tmp=head; 
    head=head->next_; 
    free(tmp); 
    } 
    head=NULL; 
    } 

    void appendNode(struct student_record_node* head, struct 
    student_record_node* newNode) 
    {  
    student_record_node *prev, *next; 

    if(head == NULL) { 
     head = newNode; 
     return; 
    } 

    next = head; 
    while(next != NULL) { 
     prev = next; 
     next = next->next_; 
    } 
    prev->next_ = newNode; 
    } 

    void printNodeList(struct student_record_node* head) 
    { 
    student_record_node *tmp = head; 

    while(tmp != NULL) { 
     tmp = tmp->next_; 
     printNode(tmp); 
    } 

    } 
+3

SO에있는 모든 링크드 목록 게시물의 약 절반은 '머리'의 로컬 복사본을 변경하고 그 기능에서 벗어날 것을 기대하면서 동일한 문제가 있습니다. 그건 그렇지 않을거야. 새 헤드를 함수 결과로 반환하거나 이중 포인터를 전달하여이 작업을 수행하는 모든 코드를 수정합니다. – ThingyWotsit

답변

0

freeNodeList에서는 학생 기록 노드가 포함 된 학생 기록이 아닌 학생 기록 노드 만 비워 둡니다. 이는 목록을 삭제 한 이후에 도달 할 수는 없지만 모든 기록이 프로그램 끝에 할당되었음을 의미합니다.

1

이 코드는 tmp를 초기화하지 않습니다

void freeNodeList(struct student_record_node* head) { 
    student_record_node *tmp; 
    while(tmp != NULL) { 
     tmp=head; 
     head=head->next_; 
     free(tmp); 
    } 
    head=NULL; 
} 

따라서, 당신은 정의되지 않은 동작을 초기화되지 않은 변수에서 읽을 때.

아마도 상태로 head != NULL을 사용해야합니다.

+0

여전히 작동하지 않습니다. –

관련 문제