释放函数外部的内存会导致双重释放或损坏错误

时间:2016-07-04 16:42:40

标签: c function pointers memory memory-management

我遇到一个问题,当我尝试释放内存时,我获得双重释放或损坏错误,在我分配了该内存块的函数之外,即使我已经将指针传递给内存块到该函数之外的指针。

我的代码在main()函数中,我调用了一个定义为char * reverseComplement(char * pattern);的函数:

char * rev = reverseComplement(dna_input);

其中dna_input是指向char内分配的已分配内存块的main()指针。在reverseComplement()函数中,有一行我在其中分配内存,然后在最后返回指向该内存块的指针。

...
...
char * revcomplpattern = (char *)malloc(strlen(pattern));
...
...
return revcomplpattern;

我认为可能导致问题的一个原因是在reverseComplement()函数完成执行后,其堆栈被拆除,因此我将失去对堆上内存的访问权限。但这不应该是因为我已经将revcomplpattern的堆分配内存的句柄从reverseComplement()传递到驻留在rev中的main()。 }。因此free(rev)中的main()应该可以胜任。

我不知道我在这里做错了什么,非常感谢任何帮助!

3 个答案:

答案 0 :(得分:0)

  

...其中dna_input是指向在main()中分配的已分配内存块的char指针。在reverseComplement()函数中,有一行我分配内存,然后在最后返回指向该内存块的指针。

你的想法告诉我你正在分配内存并以某种方式在reverseComplement()函数中使用该内存,但在函数中,你正在分配另一块内存。我不确定为什么。

  

......我遇到双重免费或损坏错误的问题......

您需要确保程序在出于任何原因退出时释放程序中所有已分配的内存块。如果没有,那么你将有内存泄漏。

如果你必须在一个函数中分配内存(我不推荐),那么你可以使用这样的代码:

char *getnewblock(int size)
{
    char *secondblock=malloc(size);
    return secondblock;
}

int main()
{
    char *myblock = malloc(1000);
    char *myblock2 = getnewblock(5000);
    free(myblock);
    free(myblock2);
    return 0;
}

上面的程序分配1000个字节的内存,然后调用一个函数来分配5000个字节的内存,然后释放两个内存块。

我真正建议您只在一个函数中分配内存,然后在子函数中使用相同的内存块,如下所示:

void insertfirstchar(char *block,char onechar)
{
   block[0]=onechar;
}

int main()
{
    char *myblock = malloc(1000);
    insertfirstchar(myblock,'A');
    free(myblock);
    return 0;
}

在上面的程序中,分配了1000个字节,然后调用一个函数使存储器块的第一个字节为字母“A”,然后释放存储器。最后一个程序可以作为起点。

答案 1 :(得分:0)

好的家伙我刚刚弄清楚了这一切!很抱歉这个麻烦!事实证明,错误不是因为我释放分配的内存的方式,而是malloc()调用。

事实证明我在分配

时所做的事情
char * revcomplpattern = (char *)malloc(strlen(pattern));

紧接着就是这些行

int strend = strlen(pattern)/sizeof(char) -1 ;
revcomplpattern[strend+1] = '\0';

我的目标是确保revcomplpattern成为字符串,因为我在其末尾插入了一个空终止符。事实证明,在索引[strend+1]时,我实际上触及了内存中未分配的位置!纠正malloc()来电后再增加一个空格

char * revcomplpattern = (char *)malloc(strlen(pattern) + 1 * sizeof(char));

free(rev)的调用不会引发错误!现在一切正常,Valgrind没有错误!特别感谢@tofro和@jdigital的建议。当我使用valgrind时,它开始告诉我strlenmalloc中出现了一个错误,我一开始就无法理解,直到我将其缩小到那条线并仔细查看它并意识到了什么错了。

伙计,我觉得GCC给出了非常神秘的错误消息,这些消息并没有多大帮助。我现在真的很困惑,如果有人能回答,为什么我的错误不会抛出SEGFAULT?我认为这会导致一个段错误,因为我触摸了未分配的内存部分???

尽管如此,谢谢大家的帮助!

答案 2 :(得分:-1)

在将控制权返回给main()之前,你是否在破坏内存?释放“有效”内存块可能会失败,因为您的malloc堆已经损坏。或者,reverseComplement()中的一些错误代码路径可能已经释放了这个内存吗?