我有一个关于释放我为c中的struct数组分配的内存的问题。
我已经搜索了已发布的问题,没有任何内容可以澄清我的问题。
首先,我事先创造了几个结构;结构中的变量都是固定大小的,例如char str[250]
或int
。
我创建了几个struct指针,并使用malloc将其转换为struct数组。
但是当我试图释放这些结构数组时,由于某种原因它不会被释放。
当我通过valgrind检查内存泄漏时,它告诉我我无法释放内存,我肯定会丢失这些struct结构的内存。
以下是与我的结构类似的一段代码;我的malloc数组上的malloc方法;以及我的自由记忆方法。
struct word{
char word[250];
int occurrence; };
struct same_word{
char word[250];};
int main(int argc, char** agrv){
FILE* fp;
fp = fopen(argv[1],"r");
if(fp == NULL)
{
perror("File does not open.");
exit(0);
}
int total_number_of_word = /*number of word I have in my txt file*/
int total_number_of_same_word = /*number of same word I have in my txt file*/
/* Assuming I knew these two numbers in advance*/
struct word* essay = malloc(total_number_of_word * sizeof(struct word));
struct same_word* unique_word = malloc(total_number_of_same_word * sizeof(struct same_word));
int index = 0;
int index2 = 0;
int ret = 0;
while(index < total_number_of_word){
fscanf(fp,"%s",essay[index].word);
essay[index].occurrence = 1;
ret = strcmp(essay[index].word,"Hello");
if( ret == 0)
{
strcpy(unique_word[index2].word,essay[index].word);
index2++;
}
index++;
}
free(essay);
free(unique_word);
fclose(fp);
}
提前致谢。
P.S 感谢所有指出我在我的问题中所犯错误的人。
答案 0 :(得分:0)
对代码进行最少的更改:
agrv
已更改为argv
。argc
之前测试argv[1]
,退出并报告失败。scanf()
的测试结果,当它不是1
时退出。#include <assert.h>
)。在Mac OS X 10.11.4 El Capitan上编译并在valgrind
下干净地运行代码。
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct word
{
char word[250];
int occurrence;
};
struct same_word
{
char word[250];
};
int main(int argc, char **argv)
{
if (argc != 2)
{
fprintf(stderr, "Usage: %s file\n", argv[0]);
return 1;
}
FILE *fp = fopen(argv[1], "r");
if (fp == NULL)
{
perror("File does not open.");
return 1;
}
int total_number_of_word = 1000;
int total_number_of_same_word = 1000;
struct word *essay = malloc(total_number_of_word * sizeof(struct word));
struct same_word *unique_word = malloc(total_number_of_same_word * sizeof(struct same_word));
assert(essay != 0);
assert(unique_word != 0);
int index = 0;
int index2 = 0;
int ret = 0;
while (index < total_number_of_word)
{
if (fscanf(fp, "%s", essay[index].word) != 1)
break;
essay[index].occurrence = 1;
ret = strcmp(essay[index].word, "Hello");
if (ret == 0)
{
strcpy(unique_word[index2].word, essay[index].word);
index2++;
}
index++;
}
fclose(fp);
free(essay);
free(unique_word);
return 0;
}
示例运行(程序名称wd
;源代码wd.c
):
$ make wd && valgrind wd wd.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror wd.c -o wd
==24802== Memcheck, a memory error detector
==24802== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==24802== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==24802== Command: wd wd.c
==24802==
==24802==
==24802== HEAP SUMMARY:
==24802== in use at exit: 22,233 bytes in 186 blocks
==24802== total heap usage: 273 allocs, 87 frees, 538,561 bytes allocated
==24802==
==24802== LEAK SUMMARY:
==24802== definitely lost: 0 bytes in 0 blocks
==24802== indirectly lost: 0 bytes in 0 blocks
==24802== possibly lost: 0 bytes in 0 blocks
==24802== still reachable: 0 bytes in 0 blocks
==24802== suppressed: 22,233 bytes in 186 blocks
==24802==
==24802== For counts of detected and suppressed errors, rerun with: -v
==24802== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 18 from 18)
$
出口处使用大量内存&#39;并且&#39;压制&#39;在Mac OS X上是正常的。
如果您遇到问题,那么一个合理的麻烦来源是您没有在两个阵列中分配足够的空间。您应该检查index
和index2
的值是否在范围内。你可能有可能减少一个词的长度 - 250相当长;我可能会用64代替。然后,您应该使用%63s
格式字符串中的scanf()
来防止溢出(或使用当前结构的%249s
)。源代码中只有136个单词,1241个字符。最长的单词&#39;每个是32个字符(malloc(total_number_of_same_word
是其中之一;另一个是strcpy(unique_word[index2].word,
)。
答案 1 :(得分:0)
感谢您的所有帮助,经过数千行代码的检查,我终于找到了程序中的问题。
因为我和另外4个人一起做小组工作。因此代码被4个不同的手触摸,我们的一个组伙伴创建了一个if语句,它将通过返回0结束程序。
但是她忘了释放我们一直在创建的所有堆内存,而且还没有发布任何代码。所以我没有抓住这个愚蠢的问题。
我将发布我们之前拥有的错误代码和我们现在所拥有的CORRECT代码,以便为可能会遇到与我们相同的愚蠢问题的人发布。
这是我们代码的错误版本
struct word{
char word[250];
int occurrence; };
struct same_word{
char word[250];};
int main(int argc, char** agrv){
FILE* fp;
fp = fopen(argv[1],"r");//argv[1] is the location where we put the txt file name
if(fp == NULL)
{
perror("File does not open.");
exit(0);
}
int total_number_of_word = /*number of word I have in my txt file*/
int total_number_of_same_word = /*number of same word I have in my txt file*/
/* Assuming I knew these two numbers in advance*/
struct word* essay = malloc(total_number_of_word * sizeof(struct word));
struct same_word* unique_word = malloc(total_number_of_same_word * sizeof(struct same_word));
int index = 0;
int index2 = 0;
int ret = 0;
while(index < total_number_of_word){
fscanf(fp,"%s",essay[index].word);
essay[index].occurrence = 1;
ret = strcmp(essay[index].word,"Hello");
if( ret == 0)
{
strcpy(unique_word[index2].word,essay[index].word);
index2++;
}
index++;
}
//...
if( /*a event is true*/)
{
/*she has forgot to free memory before the return 0
therefore we have been continuously leaking memory*/
return 0;
}
//...
free(essay);
free(unique_word);
fclose(fp);
return 0;
}
以下是out code的正确版本
struct word{
char word[250];
int occurrence;
};
struct same_word{
char word[250];
};
int main(int argc, char** agrv){
FILE* fp;
fp = fopen(argv[1],"r");//argv[1] is the location where we put the txt file name
if(fp == NULL)
{
perror("File does not open.");
exit(0);
}
int total_number_of_word = /*number of word I have in my txt file*/
int total_number_of_same_word = /*number of same word I have in my txt file*/
/* Assuming I knew these two numbers in advance*/
struct word* essay = malloc(total_number_of_word * sizeof(struct word));
struct same_word* unique_word = malloc(total_number_of_same_word * sizeof(struct same_word));
int index = 0;
int index2 = 0;
int ret = 0;
while(index < total_number_of_word){
fscanf(fp,"%s",essay[index].word);
essay[index].occurrence = 1;
ret = strcmp(essay[index].word,"Hello");
if( ret == 0)
{
strcpy(unique_word[index2].word,essay[index].word);
index2++;
}
index++;
}
//...
if(/* a event is true*/)
{
free(essay);
free(unique_word);
fclose(fp);
/* After freeing memory in here, we no longer have any memory leak*/
return 0;
}
//...
free(essay);
free(unique_word);
fclose(fp);
return 0;
}
再次感谢大家的帮助。由于我不经常在这个平台上提问,我不知道问我问题的完美方式。我很抱歉没有在第一时间创建一个最小的,完整的,可验证的例子。
但是感谢你指出,我下次问一个问题时会尽力做得更好。我非常感谢所有的解释和建议。