2015-01-09 3 views
0
#include <stdio.h> 
#include <stdlib.h> 
//why does this work with pointers thought they made a copy? 
//am i freeing memory correctly and well? 
//Something wrong with freeing 
struct Node{ 

    struct Node* next; 
    int data; 

}; 
void newNode(struct Node* trans, int val) 
{ 
    if(trans!=NULL) 
    { 
     while(trans->next!=NULL) 
     { 
      trans=trans->next; 
     } 
     //next is null create heap memory 
     trans->next=malloc(sizeof(struct Node)); 
     //checking to see if memory is created 
     if(trans->next==NULL) 
     { 
      printf("This has failed"); 
     } 
     //put in data 
     trans->next->data=val;  
     //next is null 
     trans->next->next=NULL; 
    } 

} 
void printList(struct Node* head) 
{ 
    if(head!=NULL) 
    { 
     struct Node* current; 
     current=head; 
     while(current->next!=NULL) 
     { 
      //print that current nodes data 
      printf("list is: %d\n",current->data); 
      current=current->next; 
     } 
    printf("last element is: %d\n",current->data); 

    } 
    else 
    { 
     printf("list is empty!"); 
    } 

} 
int removeLastNode(struct Node* trans) 
{ 

    //return -1 if its a empty list 
    int val=-1; 
    if(trans!=NULL) 
    { 
     /*have to access trans->next->next cause you are freeing trans->next->next and getting its val 
     then you want to set tran->next to NULL! 
     */ 
     while(trans->next->next!=NULL) 
     { 
      trans=trans->next; 
     } 
     //at end of the list? 
     val=trans->next->data; 
     //free the heap 
     free(trans->next); 
     //next points to null 
     trans->next=NULL; 

    } 
    return val; 
} 
//LOOK AT ME! 
void freeList(struct Node* root) 
{ 
    struct Node* temp; 
    struct Node* current; 
    current=root; 
    while(current->next!=NULL) 
    { 
     temp=current; 
     //going to the next one 
     current=current->next; 
     //freeing previous 
     free(temp);  
    } 
    //Am I really freeing the last one? 
    free(current); 

    root->next=NULL; 
    root=NULL; 

} 
void addingHundred(struct Node* trans) 
{ 
    int i; 
    for(i=0;i<100;i++) 
    { 
     newNode(trans,i); 
    } 
} 

int main() 
{ 
    struct Node* root; 
    //create heap mem for root 
    root=malloc(sizeof(struct Node)); 
    root->next=NULL; 
    root->data=10; 
    //traversal pointer 
    struct Node* trans; 
    //setting to point to root 
    trans=root; 
    //adding a new node.. 
    newNode(trans,8); 
    printf("value of trans after function call: %p\n",trans); 
    newNode(trans,12); 
    //value does not change 
    printf("value of trans after function call: %p\n",trans); 
    addingHundred(trans); 

    //printing the list 
    printList(root); 

    int storage; 
    //removing last node 
    storage=removeLastNode(trans); 
    //returns the last nodes value 
    printf("value removed: %d\n",storage); 
    printList(root); 
    freeList(root); 
    printList(root); 

    return 0; 
} 

위의 코드에 대한 몇 가지 질문이 있습니다. main에있는 일반적인 개념적 질문은 구조체 Node*을 취하는 newNode 함수를 호출하여이 구조체와 함께 struct Node* tran을 만듭니다. 이제 tran의 주소를 전달하지 않은 인수로 tran을 넣었습니다. 어떤 경우에는 함수 newNode 그냥 tran의 복사본을 만들 수 없으며 함수 호출 후에 함수의 모든 조작을 취소 할 수 있습니까?링크 된 목록의 함수에서 포인터 전달하기

나는 적어도 tran의 값이 newNode 함수 호출 후에 변경되지 않는다는 것을 print 문에 알았습니다. 내가 얻으려고하는 것은 연결된 목록이 어떻게 확장되고 추적 되는가입니다. 이 경우에 tran의 값을 인수로 전달하는 것이 루트 값의 힙 메모리를 처음 가리키고 단순히 힙의 메모리를 통과하지만 실제로 메모리 내용을 변경하지 않기 때문에 작동합니까?

그렇다면 목록의 노드 값을 변경하려면 &trans을 인수로 전달해야합니다. 그러나 노드를 추가하기 위해 목록을 탐색하는 중이라면 tran을 전달할 수 있습니다. 논의?

내 다른 질문은 내 freeList(struct Node* a) 기능이 올바르게 작동하지 않는다고 생각됩니다. 내가 root을 풀어서 인쇄 할 때, 대신 "목록이 비어 있습니다"라고 인쇄되거나 쓰레기가 인쇄되어 있기 때문에 소유하고 있지 않은 메모리가 원인 일 때 쓰레기 값을 인쇄합니다.

마지막으로, 여기에있는 누군가가 내 코드를 "최종 사용자 응용 프로그램 코드"로 비판했습니다. 나는 여전히 코딩에 익숙하지 않고 위의 코드가 잘못 포맷되었거나 최종 사용자 응용 프로그램 코드가된다는 것을 확신 할 수 없습니다. 누군가가 "최종 사용자 응용 프로그램 코드"작성을 피할 수있는 방법을 설명하면 많은 도움이 될 것입니다.

+0

큰 질문입니다. – gsamaras

+0

설명하지 않고 명확하게 묻는 방법을 모르겠습니다. – Nightlife

+0

코드는 작업이 성공적으로 수행되었는지 확인하기 위해 malloc (및 패밀리)의 반환 값을 항상 확인해야합니다. – user3629249

답변

2

값으로 trans을 전달하지 않으면 구조체에 대한 포인터를 Node에 전달하므로 복사본이 만들어지지 않습니다.

당신은 내가 트란의 주소

를 통과하지 못한 그 절대적으로 잘못

말, 당신이 전달하는 것은 사실 정확히이다.

당신이 그것을 호출하기 전에했던 것과 같은 주소로 정확히 newNode에 각 호출 후 trans 포인터 포인트를 포인터를 수정하지 않기 때문에 값은 변경되지 않습니다, 가치 그래서 변화가 관찰 될 수 없습니다.

당신이 newNode를 호출 할 때 새 노드가리스트의 말미에 추가됩니다, 그래서 당신은 실제로 당신이 모든 값을 볼 것 목록을 통과하는 경우, 다음과 같은 코드가

struct Node *node; 
for (node = root ; node != NULL ; node = node->next) 
    printf("value %d @ %p\n", node->val, node); 

이 값을 출력합니다 당신 각 노드의 주소를보고, 대신 당신이, 운영 체제, 그것은이 있다면 당신이 그 주소에서 메모리의 소유권을 포기처럼의 free, 값

free0 메모리에 의미, 안 그래한다에 의무 10 메모리 때문에 엄청난 성능 저하가있을 것입니다. 당신은 당신의 코드에 따라, empty을 목록을 확인하려면

, 당신은 정확히


발언 코드 내가 고정 freeList()

root = NULL; 

호출 한 후이 작업을 수행해야 : freeList 함수의 마지막에 free(current)이 있었고 마지막 노드가 두 번 해제되었습니다. 그래서 나는 또한 그것을 제거 어떤 스타일의 물건을 고정하고 질문 몸에서 printList() 기능이 훨씬 더
#include <stdio.h> 
#include <stdlib.h> 
//why does this work with pointers thought they made a copy? 
//am i freeing memory correctly and well? 
//Something wrong with freeing 
struct Node{ 

    struct Node* next; 
    int data; 

}; 
void newNode(struct Node* trans, int val) 
{ 
    if (trans != NULL) 
    { 
     while (trans->next != NULL) 
      trans = trans->next; 
     /* next is null create heap memory */ 
     trans->next=malloc(sizeof(struct Node)); 
     /* checking to see if memory is created */ 
     if(trans->next == NULL) 
      printf("This has failed"); 
     /* put in data */ 
     trans->next->data = val; 
     /* next is null */ 
     trans->next->next = NULL; 
    } 
} 
void printList(struct Node* head) 
{ 
    struct Node *node; 

    if (head == NULL) 
     printf("empty list\n"); 
    for (node = head ; node != NULL ; node = node->next) 
     printf("list is: %d\n", node->data); 
} 

int removeLastNode(struct Node* trans) 
{ 
    int val = -1; 
    /* return -1 if its a empty list */ 
    struct Node *node; 
    struct Node *last; 
    if (trans == NULL) 
     return -1; 
    /* 
    * have to access trans->next->next cause you are freeing trans->next->next and getting its val 
    * then you want to set tran->next to NULL! 
    */ 
    node = trans; 
    last = node->next; 
    while (last->next != NULL) 
    { 
     node = node->next; 
     last = node->next; 
    } 
    trans = node; 
    node = node->next; 

    /* at end of the list? */ 
    val = node->data; 
    /* free the heap */ 
    free(node); 
    /* next points to null */ 
    trans->next = NULL; 

    return val; 
} 

//LOOK AT ME! 
void freeList(struct Node* root) 
{ 
    struct Node* temp; 
    struct Node* current; 

    current = root; 
    while (current != NULL) 
    { 
     temp=current; 
     /* going to the next one */ 
     current=current->next; 
     /* freeing previous */ 
     free(temp); 
    } 
} 
void addingHundred(struct Node* trans) 
{ 
    int i; 
    for (i=0 ; i < 100 ; i++) 
     newNode(trans, i); 
} 

int main() 
{ 
    struct Node* root; 
    int   storage; 

    //create heap mem for root 
    root = malloc(sizeof(struct Node)); 

    root->next=NULL; 
    root->data=10; 

    //adding a new node.. 
    newNode(root, 8); 
    newNode(root, 12); 

    addingHundred(root); 

    //printing the list 
    printList(root); 


    //removing last node 
    storage = removeLastNode(root); 

    //returns the last nodes value 
    printf("value removed: %d\n", storage); 
    printList(root); 

    freeList(root); 

    root = NULL; 

    printList(root); 

    return 0; 
} 

내가 당신의 마지막 코멘트에 대한 이런 짓을

읽을했다. 내가 이해하지 못했지만 확실히 코드 형식을 향상시킬 수 있습니다. 공백 문자를 사용하는 것을 두려워하지 마십시오. 컴파일러는 어쨌든 문자열 리터럴을 제외하고는 무시합니다.