2011-04-11 70 views
1

我试图追捕内存泄漏,并找到一个来源。我是一个函数中的指针,并将它释放到另一个函数中,但我错过了解如何复制指针指向的值,同时也能够释放指针。复制和释放malloc'ed指针

Current implementation (with memory leak): 

// This code has been greatly simplified 
// and as such does not appear to have any purpose 
int foo(){ 
    int bestval = 0; 
    char *best; 
    char *match; 
    for (int i=0;i<3;i++) { 
     int returnValue = bar(&best); 
     if (returnValue > 10) { 
     (1) 
     match = best; 
     } 
    } 

    printf("%s", match); 
    (2)  
    return 0; 
} 


int bar(char ** best) { 
    char*s = "Hello!"; 
    *best = malloc(strlen(s) + 1); 
    strcpy(*best,s); 
    return 0; 
} 

两个问题

  1. 如果我有空闲内存在,而不是(2),我会怎么做,所以那场比赛仍然会是什么载于最好的(1) ?

  2. 我应该做strcpy复制最佳匹配?如果是这样,我是否必须在foo内做另一个malloc?

+0

假设有一个自由点二,你发布的代码不漏,但后“ 2',这个点之后匹配无效......你是否在循环中运行这段代码? – forsvarir 2011-04-11 07:23:32

+0

为什么你需要2个“最好”和“匹配”指针? (2)你可以简单地使用'best'和'free'。 – Naveen 2011-04-11 07:23:57

+0

@forsvarir,是的,我在一个循环中运行它,这就是为什么我在(1)处实现免费的原因。 – Rio 2011-04-11 07:26:26

回答

1

在黑暗中刺了一下,假设有Foo中环...

int foo() 
{ 
    int bestval = 0; 
    char *best; 
    char *match = 0; // initialize to null 

    // start some loop 
    for (int i=0;i<3;i++) {  

     // fetch the next best value... 
     int returnValue = bar(&best);  
     // some check (if best is really best!) 
     if (returnValue > 10) { 
      // if match has previously been populated, free it 
      if(match) { 
       free(match); 
      } 
      // save the new best value 
      match = best; 
     } 
     else { 
      // not saving best in match, so free it! 
      free(best); 
     } 
    } 
    // end some loop 

    // only do this if match was successful?!? 
    if(match) { 
     printf("%s", match);  
     // clean up once the best of the best has been used... 
     free(match); 
    } 
    return 0; 
} 
+0

我喜欢这个,这很有道理。我会尝试一下,并将结果报告给您! – Rio 2011-04-11 07:45:40

+0

@Rio:我刚刚添加了另一个免费的...如果你不保存最好的匹配,你需要确保你释放它... – forsvarir 2011-04-11 07:46:11

+0

最后一件事是紧紧的! – Rio 2011-04-11 07:53:55

0

您需要知道字符串的大小。
在(1)您将分配已经释放的内存地址的地址,如果您想释放最佳空间,则必须对另一个malloc执行match*=malloc(sizestr)然后将其复制为memmove或strcpy。

如果我理解正确,你想复制到最好的字符串,然后释放最好的内存和分配ptr匹配?如果在移动或strcpying到另一个位置之前释放最佳内存,则会丢失其内容,并且如果您想先将其复制到另一个位置,则需要分配要将其复制到的内存,因此您需要在该代码上使用2个malloc 。

0

如果我不得不在(1)而不是(2)处释放记忆,我该怎么做才能让匹配仍然具有最好的内容?

如果free(1)位置,这是不可能做到这一点,使match仍然会有什么载于best

我应该做strcpy来复制最佳匹配吗?如果是这样,我是否必须在foo内做另一个malloc?

match = best; 

上面的说法,两者都指向同一个位置。所以,根本不需要strcpy。为此,请为match分配内存以指向其长度为best+1,然后执行strcpy

0

复制指针的值不会复制底层内存。因此,不要free(best),直到你完成match,或者你需要malloc一个新的缓冲区,例如, memcpy()从一个缓冲区到另一个缓冲区的内容。

1

在功能栏中的strcpy应为

strcpy(*best,s); 

在主函数中,你可以通过

strcpy(match, best); 
free(best); 

比赛之前需要指向一个有效的内存块的价值最好的点复制到。如果你做一个

match = best; 
free(best); 

匹配将是无效的,因为它指向相同的释放最好的指针。

+0

'delete'是C++的,需要'free()'在这里... – 2011-04-11 07:29:00

+0

你'关于strcpy。我修正了这个问题。 – Rio 2011-04-11 07:29:41

+0

对不起,仍然有点用C++ ;-)修正。 – hirschhornsalz 2011-04-11 07:31:13

0

是的,你可以mallocstrcpy:如果你不已经

match = strdup(best); 

match = malloc(strlen(best) + 1); 
strcpy(match, best); 

但是,如果你的实现提供了它,你可以使用strdup()功能,更容易有strdup(),最好自己创建一个。

0

您当前的任务只是将指针分配给相同的缓冲区。如果你接着这个缓冲区,你已经删除了这里包含的内容(因此解引用它是一个坏主意)。
您无需使用strcpy()复制最佳匹配 - 在printf()(或需要的最后一点)之后,您最好将其释放。用一个额外的函数调用或六个函数调用过于复杂的东西是没有意义的,只要记住在每个函数结束时分配的内存。