好的,我有这段code:
typedef struct faux_crit
{
char dna[DNALEN+1]; //#define'd to 16
int x, y;
int age;
int p;
int dir;
} crit;
crit *makeguy(int x, int y)
{
crit *guy;
guy = (crit *) malloc(sizeof(crit));
strcpy(guy->dna, makedna());
guy->x = x;
guy->y = y;
guy->age = guy->p = guy->dir = 0;
return guy;
}
char *makedna()
{
char *dna;
int i;
dna = (char *) malloc(sizeof(char) * DNALEN+1);
for(i = 0; i < DNALEN; i++)
dna[i] = randchar();
return dna;
}
int main()
{
int i;
crit *newguy;
srand((unsigned) time(0));
newguy = makeguy(0, 0);
/*[..]
just printing things here
*/
free(newguy);
return 0;
}
我只想知道管理内存有什么问题,因为valgrind会报告内存错误。我认为它是makedna中的dna var,但我什么时候应该释放它?离开功能后我无法访问它,我需要将其返回,所以在此之前我无法释放它。
编辑:好的,谢谢大家。答案 0 :(得分:9)
最简单的解决方法是更改makeguy(),如下所示:
char* dna = makedna();
strcpy(guy->dna, dna);
free(dna);
但这不是一个好的解决方案,因为你在一个位置分配内存并在其他位置释放它。最好在同一个地方做malloc和free。所以我建议将makedna()更改为:
void* makedna(char* dna, int dna_len)
{
int i;
for(i = 0; i < dna_len; i++)
dna[i] = randchar();
}
您可以像这样调用makedna():
char* dna = (char*)malloc(DNALEN+1);
makedna(dna, DNALEN);
dna[DNALEN] = 0;
strcpy(guy->dna, dna);
free(dna);
现在makedna()只做预期的事情:做一个dna序列。内存管理应由呼叫者处理。此外,如果在不同的呼叫站点需要,此解决方案可以灵活地使用静态字符数组。
答案 1 :(得分:7)
你应该这样做:
char *tempdna = makedna();
strcpy(guy->dna, tempdna);
free(tempdna);
但是要使strcpy
起作用,你的makedna
函数需要对字符串进行零终止。最后,就在回归之前,有:
dna[DNALEN] = 0;
答案 2 :(得分:3)
您应该将makedna()
的指针存储到strcpy
之前,以便在完成后将其释放。
char* dna = makedna();
strcpy(guy->dna, dna);
free(dna);
答案 3 :(得分:2)
您应该更改makedna()以获取参数:
void makedna(char* dna)
{
int i;
for(i = 0; i < DNALEN; i++)
{
dna[i] = randchar();
}
}
为了清晰起见,请注意额外的括号
和第14行变为:
makedna(guy->dna);
这避免了至少有一套关于malloc和free的麻烦
修改强>
此解决方案也避免了strcpy的任何空终止问题。
答案 4 :(得分:0)
makedna
函数有关。但是,该功能没有任何问题。它更多地是关于你如何使用它。
makedna
完全可以返回指向已分配内存的指针。但是,调用函数可以在完成后释放该内存。
因此我建议你改变:
crit *guy;
guy = (crit *) malloc(sizeof(crit));
strcpy(guy->dna, makedna());
为:
crit *guy;
guy = (crit *) malloc(sizeof(crit));
char * dna = makedna();
strcpy(guy->dna, dna);
// Now that we copied the content of the dna string
// we can free it.
free(dna);
编辑:作为Chris Jester-Young points out,您的makedna
功能也存在小问题。您需要对从该函数返回的值进行null终止,以便strcpy
可以正常工作。在返回结果之前,在makedna
函数中添加它:
dna[DNALEN] = 0;
答案 5 :(得分:0)
fbereton是对的 - 你不需要用于DNA的malloc。
但是,如果你将malloc内存存储在你的结构中,关键是你不能只释放结构并期望释放其他内存分配。在释放结构本身之前,您需要释放结构内的所有分配。
答案 6 :(得分:-1)
第3行:dna [DNALEN + 1] //包含[DNALEN + 1]元素的静态声明数组 - 已分配内存 第25行:由于数组已经存在,因此不需要malloc