【发布时间】:2016-03-28 06:12:14
【问题描述】:
我的代码给出了 glibc 错误。有人可以指出我的错误。 此代码用于标记单词。我如何使用 GDB 或任何其他有用的工具来解决这些问题。代码如下
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <string.h>
struct token
{
char *token;
int length;
};
void freeing(gpointer item)
{
free(((struct token*)item)->token);
}
int main(int argc, char* argv[])
{
int start1 = 0, start2 = 0, i =0;
struct token *tk = NULL;
char line[256], *temp = NULL;
FILE *fp1 = NULL;
FILE *fp2 = NULL;
GSList *list = NULL, *iterator = NULL;
fp1 = fopen(argv[1], "r");
fp2 = fopen(argv[2], "w+");
if (NULL == fp1)
{
fprintf(stderr,"cant open %s",argv[1]);
return 1;
}
if (NULL == fp2)
{
fprintf(stderr,"cant open %s",argv[2]);
return 1;
}
while (1)
{
if (NULL == fgets(line, 255, fp1))
break;
tk = (struct token *)malloc(sizeof(struct token));
start1 = -1; start2 = -1;
for(temp = line,i = 0; temp[i] != '\n'; i++)
{
if ((temp[i] == ',') || (temp[i] == ' ') || (temp[i] == ';') || (temp[i] == '.'))
start2 = i;
if (start1 == start2)
continue;
tk->token = strndup(line + (start1+1), start2 - (start1+1));
tk->length = strlen(tk->token);
list = g_slist_append(list, tk);
start1 = start2;
}
tk->token = strndup(line + (start1+1), strlen(line));
tk->length = strlen(tk->token);
printf("\ntk->length : %d\n",tk->length);
list = g_slist_append(list, tk );
}
for (iterator = list; iterator; iterator = iterator->next)
{
printf("%s -> ",((struct token *)(iterator->data))->token);
printf("%d\n",((struct token*)iterator->data)->length);
}
g_slist_foreach(list, (GFunc)freeing, NULL);
fclose(fp1);
fclose(fp2);
return 0;
}
【问题讨论】:
-
请格式化您的代码,删除不必要的强制转换并一致缩进。
-
list = g_slist_append(list, tk);在for循环中以相同的tk值重复调用。也就是说,您将同一元素多次排队。因此多次释放同一个令牌。因此,第一次免费将成功,任何后续免费将导致您显示的错误。请注意,您的代码中还有其他错误,例如内存泄漏和内存损坏。一个很好的内存问题调试工具是valgrind -
我正在为每个已读取的新令牌分配新空间并将其存储在列表中。这不对吗??
-
分配给
tk->token,但它们都属于同一个tk。也就是说,每次进行新分配时,都会覆盖旧的tk->token值。这会导致内存泄漏以及您看到的双重释放错误。如果看不到,请在freeing函数的开头添加printf("%p\n", item)。您会发现重复的相同值。 -
不,我不能。 1. 由于已经指出的不一致缩进,代码几乎不可读。 2. 你没有详细解释代码应该做什么。你说过这是“标记词”,但这并不是一个完整的描述。
标签: c memory-management memory-leaks free glibc