【发布时间】:2020-09-22 06:08:08
【问题描述】:
我做了一个程序,它从一个文件中读取单词,对它们进行排序并插入到列表中,然后我将列表打印到新文件中。单词必须按字母顺序排序。我使用 strcmp() 函数来比较它们,并创建了函数 MakeLowerCase()。它将字符串“转换”为小写字符串。我知道该程序进行了很多操作,但我不知道如何优化它。无论如何,我必须摆脱内存泄漏,但我不知道它泄漏在哪里。
我从 Dr Memory 那里得到了这样的报告(只是其中的一部分):
error #5: LEAK 2 direct bytes 0x01373d60-0x01373d62 + 0 indirect bytes
# 0 replace_malloc [d:\drmemory_package\common\alloc_replace.c:2577]
# 1 msvcrt.dll!_strdup
# 2 .text
# 3 __mingw_glob
# 4 _setargv
# 5 .text
# 6 ntdll.dll!__RtlUserThreadStart
Error #6: LEAK 11 direct bytes 0x01373db0-0x01373dbb + 0 indirect bytes
# 0 replace_malloc [d:\drmemory_package\common\alloc_replace.c:2577]
# 1 MakeItTxt
# 2 main
Error #7: LEAK 6 direct bytes 0x01374f10-0x01374f16 + 0 indirect bytes
# 0 replace_malloc [d:\drmemory_package\common\alloc_replace.c:2577]
# 1 MakeLowerCase
# 2 sortedInsert
# 3 InsertWordsToStruct
# 4 main
Error #8: LEAK 6 direct bytes 0x01374f38-0x01374f3e + 0 indirect bytes
# 0 replace_malloc [d:\drmemory_package\common\alloc_replace.c:2577]
# 1 MakeLowerCase
# 2 sortedInsert
# 3 InsertWordsToStruct
# 4 main
Error #9: LEAK 4 direct bytes 0x013750a0-0x013750a4 + 0 indirect bytes
# 0 replace_malloc [d:\drmemory_package\common\alloc_replace.c:2577]
# 1 MakeLowerCase
# 2 sortedInsert
# 3 InsertWordsToStruct
# 4 main
Error #10: LEAK 6 direct bytes 0x013750c8-0x013750ce + 0 indirect bytes
# 0 replace_malloc [d:\drmemory_package\common\alloc_replace.c:2577]
# 1 MakeLowerCase
# 2 sortedInsert
# 3 InsertWordsToStruct
# 4 main
Reached maximum leak report limit (-report_leak_max). No further leaks will be reported.
===========================================================================
FINAL SUMMARY:
DUPLICATE ERROR COUNTS:
Error # 1: 8
Error # 2: 8
Error # 4: 3
Error # 7: 137
Error # 8: 137
Error # 9: 4855
Error # 10: 4854
SUPPRESSIONS USED:
ERRORS FOUND:
0 unique, 0 total unaddressable access(es)
3 unique, 17 total uninitialized access(es)
0 unique, 0 total invalid heap argument(s)
0 unique, 0 total GDI usage error(s)
0 unique, 0 total handle leak(s)
0 unique, 0 total warning(s)
7 unique, 9988 total, 68700 byte(s) of leak(s)
0 unique, 0 total, 0 byte(s) of possible leak(s)
ERRORS IGNORED:
10 unique, 12 total, 421 byte(s) of still-reachable allocation(s)
我可以与您分享我的部分代码(报告中的函数):
char* MakeLowerCase(char* word)
{
char* lower = (char *)malloc(sizeof(char)*strlen(word)+1);
strcpy(lower, word);
int i = 0;
for(i = 0; i < strlen(lower); i++){
lower[i] = tolower(lower[i]);
}
return lower;
}
Word* newItem(char* word)
{
/* allocate node */
Word* new_item = (Word *)malloc(sizeof(Word));
int word_length = strlen(word);
new_item->word = (char *)malloc((word_length+1)*sizeof(char));
strcpy(new_item->word, word);
new_item->pNext = NULL;
return new_item;
}
void sortedInsert(Word** pH, Word* new_node)
{
Word* current;
/* Special case for the head end */
if (*pH == NULL || strcmp(MakeLowerCase((*pH)->word), MakeLowerCase(new_node->word)) == 1)
{
new_node->pNext = *pH;
*pH = new_node;
}
else
{
/* Locate the node before the point of insertion */
current = *pH;
while (current->pNext!=NULL &&
strcmp(MakeLowerCase(current->pNext->word), MakeLowerCase(new_node->word)) == -1)
{
current = current->pNext;
}
new_node->pNext = current->pNext;
current->pNext = new_node;
}
}
void InsertWordsToStruct(Word** pH, FILE* filename){
char single_line[16384]; /* longest posible line in my code */
int number_of_words = 0;
int counter = 0;
while(fgets(single_line, 16384, filename))
{
char* single_word = strtok(single_line, " \t\n\0"); /* cut one word from line */
while(single_word != NULL)
{
if(IsLegitWord(single_word) == true) /* function return true if word is really word */
{
Word* new_node = newItem(single_word);
sortedInsert(pH, new_node);
}
single_word = strtok(NULL, " \t\n\0");
}
}
}
我真的找不到漏洞。我是C新手,对不起。 当然,在我在 main 中使用的文件末尾:
RemoveWordList(&listname);
功能:
void RemoveWordList(Word** pH){
Word* current = *pH;
while (current != NULL){
Word* next = current->pNext;
free(current->word);
free(current);
current = next;
}
free(current);
*pH = NULL;
}
^但我认为问题不在这里。^ 你有什么想法吗?你可以帮帮我吗?
【问题讨论】:
-
您真的需要在
MakeLowerCase内复制吗?如果没有,那么您可以直接在传递的内存位置进行转换。 -
我永远不会理解新程序员对链表的迷恋,你永远不会在实际的软件中使用它们,因为它们会完全杀死你的缓存,容易出错(一遍又一遍地证明)和很大,在内存方面。
-
@Blindy 当你还是一个新程序员的时候,你有没有实现过链表? :) 你说的是真的,但是它们确实具有有用的属性并且在很多场合都是有保证的。
-
@Blindy 这不是我的选择,只是学校的标准 :)
标签: c pointers memory struct memory-leaks