2013-04-28 53 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)); 
    }