2013-04-28 3 views
0

이 함수 (tmap_insert)는 이상한 일을합니다. 나는 그것을 루프라고 부르며, 어떤 이유로 새로운 항목을 추가 할 때마다 트리에 이전에 추가 된 모든 항목의 item-> name (item-> val!이 아닌)을 겹쳐 씁니다. 가장 최근의 추가 내가보기에 여기에 내 코드를 게시했습니다. 꽤 길지만 그것에 대해 할 수있는 일이별로 없습니다.C : 값이 변경/덮어 쓰기 중임

또한 관련 구조체와이를 루프에서 호출하는 함수를 포함했습니다. tmap_create(char *fname)에서

int tmap_insert(TMAP_PTR t, char * name, double val){ 
    TMAP_PTR parent = malloc(sizeof(struct tmap_struct)); 
    TMAP_PTR new = malloc(sizeof(struct tmap_struct)); 
    NAME_VAL* temp = malloc(sizeof(NAME_VAL)); 
    temp->name = name; 
    temp->value = val;   
    new->item = temp;  
    new->size = 1; 
    new->height = 0; 
    while (t != NULL) 
    { 
     t->size = t->size + 1; 
     if (val > (t->item)->value) 
     { 
      parent = t; 
      t = t->right; 
     } 
     else if (val < (t->item)->value) 
     { 
      parent = t; 
      t = t->left; 
     } 
    } 
    if (parent != NULL) 
    { 
     new->parent = parent; 
     if (val > (parent->item)->value) 
     { 
      parent->right = new; 
     } 
     else if (val < (parent->item)->value) 
     { 
      parent->left = new; 
     } 
    } 
    TMAP_PTR unbalanced = malloc(sizeof(struct tmap_struct)); 
    unbalanced = NULL; 
    TMAP_PTR iterator = malloc(sizeof(struct tmap_struct)); 
    iterator = new->parent; 
    while (iterator != NULL) 
    { 
     if (iterator->left != NULL && iterator->right != NULL) 
     { 
      if ((iterator->left)->size > (2*((iterator->right)->size) + 1) || (iterator->right)->size > (2*((iterator->left)->size) + 1)) 
      { 
       unbalanced = iterator; 
      } 
      if ((iterator->left)->height > (iterator->right)->height) 
      { 
       iterator->height = (iterator->left)->height + 1; 
      } 
      else 
      { 
       iterator->height = (iterator->right)->height + 1; 
      } 
     } 
     else if (iterator->left != NULL) 
     { 
      if ((iterator->left)->size > 1) 
      { 
       unbalanced = iterator; 
      } 
      iterator->height = (iterator->left)->height + 1; 
     } 
     else 
     { 
      if ((iterator->right)->size > 1) 
      { 
       unbalanced = iterator; 
      } 
      iterator->height = (iterator->right)->height + 1; 
     }   
     iterator = iterator->parent; 
    } 
    if (unbalanced != NULL) 
    { 
     NAME_VAL **arr = malloc(unbalanced->size * sizeof(NAME_VAL*)); 
     int i;   
     for (i = 0; i < unbalanced->size; i++) 
     { 
      arr[i] = malloc(sizeof(NAME_VAL)); 
     } 
     int *index = malloc(sizeof(int)); 
     *index = 0;   
     arr = make_arr(unbalanced, arr, index); 

     int pos = ((unbalanced->size)/2); 

     TMAP_PTR head = malloc(sizeof(struct tmap_struct)); 
     head->size = 1; 
     head->height = 0; 
     head->item = arr[pos]; 
     rebalance(arr, 0, pos-1, head); 
     rebalance(arr, pos+1, unbalanced->size, head); 
     unbalanced->parent = head->parent; 
     if ((unbalanced->parent)->right == unbalanced) 
     { 
      (unbalanced->parent)->right = head; 
     } 
     else 
     { 
      (unbalanced->parent)->left = head; 
     } 
    } 
    return 1; 
} 


TMAP_PTR tmap_create(char *fname){ 
    printf("%s", fname); 
    fflush(stdout); 
    FILE *src; 
    src = fopen(fname, "r"); 
    if (src == NULL) 
    { 
     printf("File could not open!\n"); 
     return; 
    } 
    double value; 
    char name[20]; 

    TMAP_PTR head = malloc(sizeof(struct tmap_struct)); 
    head->size = 1; 
    head->height = 0; 

    fscanf(src, "%s", name); 
    fscanf(src, "%lf", &value); 
    head->item = malloc(sizeof(NAME_VAL)); 
    (head->item)->value = value; 
    (head->item)->name = name; 

    while (fscanf(src, "%s %lf", name, &value) == 2) 
    { 
     printf("%s", name); 
     fflush(stdout); 
     tmap_insert(head, name, value); 
    } 
    return head; 

} 

struct tmap_struct{ 
    TMAP_PTR parent; 
    TMAP_PTR left; 
    TMAP_PTR right; 
    int height; 
    int size; 
    NAME_VAL* item; 
}; 

typedef struct name_val { 
    char *name; 
    double value; 
}NAME_VAL; 
+2

'문자 이름 [20]'넌 쿄코> name' 부재는 동일한 배열을 가리 '모두시키는된다. 공백을 할당하고 이름을 복사해야합니다. –

+5

특히, 삽입 프로 시저의'temp-> name = name'. 그게 잘못된 길이야. 그리고 부수적으로,이 코드에는 ** eleven **'malloc()'호출이 있으며, 아무 곳이나 하나의'free()'* 호출이 아닙니다. 당신이 그 일을 돌볼 거라 믿습니다. – WhozCraig

+0

나는 그것을 확실히 처리 할 것이지만 메모리 누수에 대해 너무 걱정하기 전에 코드를 작동시켜야한다. 아직도 버그를 찾는 데 어려움이 있습니다. 그것은 temp-> name = name입니까? temp-> name = malloc (20)을 추가 한 다음 temp-> name = name을 추가했지만 도움이되지 않았습니다. – SwiftCore

답변

0

당신은 당신이 그것에 이름의 새 값을 읽을 루프의 각 단계에서 다음, 이름 문자의 배열을 할당하고, 새로운 노드를 작성 기능 tmap_insert, 그것을 통과 char 배열에 대한 포인터를 저장한다. 따라서 분명히 트리의 모든 노드는 동일한 문자 배열을 가리키며, 새로운 문자열을 저장하면 모든 노드가 새로운 값을 보게됩니다. 해결 방법은 저장해야하는 각 이름에 대해 새 char 배열을 할당하는 것입니다. 당신과 함께) tmap_create (의 while 루프를 교체해야

char* name = malloc(20*sizeof(char)); 
while (fscanf(src, "%s %lf", name, &value) == 2) 
    { 
     printf("%s", name); 
     fflush(stdout); 
     tmap_insert(head, name, value); 
     name = malloc(20*sizeof(char)); 
    }  
관련 문제