C内存管理初学者问题

时间:2009-08-23 16:01:56

标签: c memory-management

好的,我有这段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,但我什么时候应该释放它?离开功能后我无法访问它,我需要将其返回,所以在此之前我无法释放它。

编辑:好的,谢谢大家。

7 个答案:

答案 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