2016-07-16 4 views
-2

저는 C로 데이터 구조를 배우 았으며 같은 코드를 구현하고 있다고 생각합니다. 아래 코드와 그 이상한 출력, 추가 레코드 기능에 표시 될 때 올바른 데이터 표시 함수가 메인에서 값이 변경되면 호출됩니다. 값에 의한 호출과 관련이 있지만 정확한 이유는 알 수 없습니다.링크 목록 추가 기능이 예상대로 작동하지 않습니다.

PS : 값이

변경하는 추가 기능 후 메인로부터 호출 될 때, 프로그램이 너무 길거나 아닌 기준에 따라 경우 미안

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

struct record; 
typedef struct record data_record; 

struct record{ 
    int data; 
    struct record *next_record; 
}; 

// forward function declarations 
data_record *get_record(); 
void initialize_record(data_record *,int); 
void display_record(data_record *); 
void display_list(data_record *,int); 
data_record *generate_link_list(data_record *,int); 
void add_record(data_record *,data_record,int); 

int main(int argc,char *argv[]) 
{ 
    printf("Initializing the data ... \n"); 
    printf("Data length: %d \n",sizeof(data_record)); 
    int array_length = 5; 

    data_record *start; 
    // generate_list function 
    start = generate_link_list(start,array_length); 
    printf("------------------------------------\n\n"); 
    display_list(start,array_length); 
    printf("Address : %x \n",start); 

    // add the extra item to the existing list 
    data_record record; 
    record.data = 100; 
    record.next_record = NULL; 
    add_record(start,record,2); 
    display_list(start,array_length +1); 

    printf("Terminating the program \n"); 
    return 0; 
} 

data_record *get_record() 
{ 
    return (data_record *)malloc(sizeof(data_record)); 
} 

void initialize_record(data_record *record,int data) 
{ 
    record->data = data; 
    record->next_record = NULL; 
} 

void display_record(data_record *record) 
{ 
    printf("Printing data: \t"); 
    printf("Data: %d \t",record->data); 
    printf("Next Item address: %x \n",record->next_record); 
} 

void display_list(data_record *list,int length) 
{ 
    data_record *list_pointer = list; 
    printf("Printing the list: \n"); 
    int index; 
    for(index = 0;index < length;index++) 
    { 
     display_record(list_pointer); 
     list_pointer = list_pointer->next_record; 
    } 
    printf("Done with the printing \n"); 
} 

data_record *generate_link_list(data_record *list,int array_length) 
{ 
    list = get_record(); 
    initialize_record(list,0); 
    data_record *current_record_pointer, *record; 
    int index = 0; 

    current_record_pointer = list; 

    printf("First record: "); 
    display_record(current_record_pointer); 

    for(index = 1;index < array_length;index ++) 
    { 
     record = get_record(); 
     initialize_record(record,index); 
     current_record_pointer->next_record = record; 
     current_record_pointer = record; 
    } 
    return list; 
} 

void add_record(data_record *list,data_record record,int position) 
{ 
    printf("Start address %x \n",list); 
    printf("New record address %x \n",&record); 
    data_record *list_pointer = list; 
    int list_position = 0; 
    for(list_position = 0;list_position < position - 1;list_position ++) 
    { 
     list_pointer = list_pointer->next_record; 
    } 
    if(list_pointer != NULL) 
    { 
     data_record *next_record = list_pointer->next_record; 
     list_pointer->next_record = &record; 
     record.next_record = next_record; 
    } 
    display_list(list,6); 
} 

추가 함수 호출 display_list 정확하지만 같은 도시

답변

2

add_record으로 전달 된 record은 의 복사본 인 main입니다. 이것이 매개 변수가 구조 일 때 값에 의한 전달이 작동하는 방식입니다. 따라서 record으로 변경하면 원본에 영향을 미치지 않고 사본에만 영향을 미칩니다.

이 문제를 해결 포인터

void add_record(data_record *list,data_record *record,int position) 
{ 
    ... 

    list_pointer->next_record = record; 
    record->next_record = next_record; 

    ... 
} 

record을 선언하고 main

add_record(start,&record,2); 

사이드 노트에 기록의 주소를 전달합니다 : 그것은에 start을 통과 무의미 generate_link_liststart에는 generate_link_list에 필요한 정보가 포함되어 있지 않으므로 또는 사용.

data_record *generate_link_list(int array_length) 
{ 
    data_record *list = get_record(); 

    ... 
} 

또 다른 참고 : 그래서으로 변경 코멘트에 @JonathanLeffler에 의해 지적, 당신은 항상 기록을 만들 수 get_record 기능을 사용해야합니다. 나는 더 멀리 가서 get_recordinitialize_record을 하나의 함수 create_record으로 결합해야한다고 말했습니다.

data_record *create_record(int data) 
{ 
    data_record *record = malloc(sizeof(data_record)); 
    if (record) 
    { 
     record->data = data; 
     record->next_record = NULL; 
    } 
} 

그런 다음 main의 코드가 목록에있는 모든 레코드에 대한 create_record를 사용하여

// add the extra item to the existing list 
data_record *record = create_record(100); 
if (record) 
    add_record(start,record,2); 
display_list(start,array_length +1); 

이되고, 당신은 안전하게 목록에 free 항목이 필요한 때.

+1

정말로주의를 기울이면,'main()'에 정의 된'data_record record; '가 있고 수정 된 코드의 주소로'add_record()'에 전달되었음을 알 수 있습니다. 이 대답 (현재 프로그램)에서는 정상적으로 작동하지만 목록에 할당 된 메모리를 해제하려는 경우 할당되지 않은 레코드가 재난의 원인이됩니다. 목록에 모든 노드를 균등하게 할당해야합니다. 그렇게하지 않으면 목록과 관련된 메모리를 해제하기가 ​​매우 어려워집니다. –

관련 문제