C:正在更改/覆盖的值

时间:2013-04-28 22:11:27

标签: c

所以这个函数(tmap_insert)正在做一些好奇的事情。我在一个循环中调用它,并且出于某种原因,每当我添加一个新项目时,它会覆盖树中所有先前添加的项目的item-> name(但不是item-> val!),给它最近添加的名称。我已经在这里发布了我的代码供您查看 - 它已经很长了但是我无能为力。

另外,我已经包含了相关的结构,以及在循环中调用它的函数。

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;

1 个答案:

答案 0 :(得分:0)

tmap_create(char *fname)中为name分配一个char数组,然后在循环的每一步中读入name的新值,并将其传递给函数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));
    }