【发布时间】:2013-04-28 22:11:26
【问题描述】:
所以这个函数(tmap_insert)正在做一些奇怪的事情。我在一个循环中调用它,并且由于某种原因,每当我添加一个新项目时,它都会覆盖树中所有先前添加的项目的项目->名称(但不是项目-> 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;
【问题讨论】:
-
char name[20];你让所有thing->name成员指向同一个数组。您需要分配空间并复制名称。 -
具体来说,
temp->name = name在插入过程中。那是错误的做法。附带说明一下,此代码中有 11 个malloc()调用,而不是一个free()anywhere 调用。我相信你会解决这个问题的。 -
我肯定会解决这个问题,但我需要让代码正常运行,然后再过分担心内存泄漏。我仍然无法找到错误。是 temp->name = name 吗?我添加了 temp->name = malloc(20),然后添加了 temp->name = name,但这似乎没有帮助。
-
这就是所谓的内存泄漏(您的注释代码)。你熟悉
strlen()和strcpy()这两个函数吗?如果在 POSIX 系统上,您是否熟悉函数strdup()(我并不真正推荐它,但它通常不可用)。 -
我熟悉
strlen()和strcpy()。我已经用strdup()刷了一遍,但我用的不多……让我试试。我将分配更改为temp->name = malloc(20); strcpy(temp->name, name);,但仍然没有修复。
标签: c