2013-04-28 103 views
0

所以這個函數(tmap_insert)正在做一些好奇的事情。我在一個循環中調用它,出於某種原因,它會覆蓋樹中所有以前添加的項目的item-> name(但不包括item-> val!),只要我添加一個新項目,給它的名稱最近的增加。我已經在這裏發佈了我的代碼供您查看 - 這段時間很長,但我可以做的並不多。C:正在更改/覆蓋的值

另外,我已經包含了相關的結構,以及在循環中調用它的函數。

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'成員指向同一陣列。您需要分配空間並複製名稱。 – 2013-04-28 22:16:04

+5

具體來說,插入過程中的'temp-> name = name'。那是錯誤的做法。還有一個方面,在這段代碼中有** 11''malloc()'調用,而不是任何地方都有一個'free()'* *。我相信你會照顧的。 – WhozCraig 2013-04-28 22:17:43

+0

我絕對會照顧到這一點,但在我擔心內存泄漏太多之前,我需要讓代碼正常工作。我仍然無法找到該錯誤。它是temp-> name = name嗎?我添加了temp-> name = malloc(20),然後temp-> name = name,但這似乎沒有幫助。 – SwiftCore 2013-04-28 22:25:09

回答

0

tmap_create(char *fname)你分配字符的名稱的數組,然後你在它讀名稱的新值的循環的每一步,並把它傳遞給函數tmap_insert,在那裏你創建一個新的節點,在其中存儲指向char數組的指針。所以,很顯然,樹的所有節點都指向同一個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)); 
    }