【问题标题】:Memory Leaking - C内存泄漏 - C
【发布时间】:2016-01-27 06:35:20
【问题描述】:

在同一个文件中,我有两个例程。第一个将存储一个文件中的一些字节。另一个会将此信息提供给将处理该信息的例程。

boolean
adin_memory(char* buffer, int size_chunck, int end_flag){
    real_data=(SP16 *)malloc(size_chunck); //real_data -->global
    memcpy(&(real_data[0]),&(buffer[0]),size_chunck);

    pos_write += size_chunck;
    global_size = size_chunck;
    global_end_flag = end_flag;
    //end_flag = 1 --> end of Stream
    //end_flag = 0 --> Streaming
    return TRUE;
}

为了防止泄漏的可能性,我使用了malloc。但是这个例程被调用了好几次。所以,在adin_memoryadin_read (将是free)的一些重复之后,我认为内存开始碎片化(我可以看到任务管理器中输入文件大小的泄漏 - RAM 的增量) .那正确吗?我怎样才能防止这种情况?要查看此泄漏,我在 adin_memory 的开头和结尾放置了一个断点,然后查看任务管理器。

int
adin_read(SP16 *buf, int sampnum)
{
  FILE *fp;
  int cnt = 0;
  fp = gfp;

  //(.......)
    if(global_end_flag == 1 || pos_write == pos_read){ return -1;}

    for(i = pos_read/sizeof(SP16); i <= sampnum; i++){
         if(i >= pos_write/sizeof(SP16)) {              
             cnt = i;
             //(....)
             break;
         }
         buf[i] = real_data[i];
     }
     pos_write = 0; 
     //(....)
     free(real_data);
     return cnt;
}

【问题讨论】:

  • 这有助于避免堆碎片 -stackoverflow.com/questions/150753/…
  • To prevent leaking I am using malloc. ???错字?
  • adin_read 释放real_data 之前,您是否再次致电adin_memory?因为这会泄漏real_data的当前值所指向的内存。
  • @IanAbbott 您的意思是“双重免费泄漏”吗?现在你这么说我认为是可能的。让我检查一下..
  • 我认为 Ian 指的是通过分配新分配的内存来覆盖全局句柄的情况。另外,如果你释放一个全局变量,你应该将它设置为NULL 以避免重复frees。

标签: c memory-leaks


【解决方案1】:
int
adin_read(SP16 *buf, int sampnum)
{
  FILE *fp;
  int cnt = 0;
  fp = gfp;

  //(.......)
    if(global_end_flag == 1 || pos_write == pos_read){
       /* Leak is possibly here. You return without freeing.
          Ensure free is called here also. And it is good practice to
          make the freed pointer point to NULL so you can check and
          avoid double free problems. */       
       return -1;
    }

    for(i = pos_read/sizeof(SP16); i <= sampnum; i++){
         if(i >= pos_write/sizeof(SP16)) {              
             cnt = i;
             //(....)
             break;
         }
         buf[i] = real_data[i];
     }
     pos_write = 0; 
     //(....)
     free(real_data);
     return cnt;
}

【讨论】:

  • 感谢您的提示,但泄漏仍然存在。我会尝试在代码中的某个地方查找
【解决方案2】:

如果没有进一步描述您如何使用这些功能的上下文,很难说,但是...

每次调用adin_memory() 函数时,它都会分配一些内存(通过调用malloc),然后设置real_data 指向新分配的内存。

如果real_data 已经指向一些分配的内存,那么你只是泄露了它。

所以如果你的主程序调用adin_memory() 3 次,然后调用adin_read(),那么你会泄漏两块内存,只释放最后一块。

【讨论】:

  • 顺序是... adin_memory() , adin_read(), adin_memory() ... 没有其他方式。
  • 如果你总是在调用adin_memory() 之后调用adin_read(),那么你的泄漏很可能是由于@cenouro 正确识别的adin_read() 的提前返回。
  • 我已经测试了该选项。但没有成功。免费过程进展顺利(我猜)。但是在每 5/6 次执行的 adin_memory() 中,我会有一个泄漏。我正在尝试寻找其他分配内存的方式。
  • @carduh 你有任何确凿的证据证明实际泄漏吗? RAM 使用率可能会因多种原因而增加。您的调试器是否报告了泄漏(如果有能力)?
  • 显然我已经解决了这个问题。并且没有更多的增量。 @GrahamS
【解决方案3】:

改变

if(global_end_flag == 1 || pos_write == pos_read){ return -1;}

if(global_end_flag == 1 || pos_write == pos_read)
{
    free(real_data);
    return -1;
}

【讨论】:

    【解决方案4】:

    问题确实出在连续的 malloc/free 中(导致内存碎片)。删除后,我创建了一个指向传入字节的全局指针。并在adin_read() 中制作memcpy

    int adin_read(SP16 *buf, int sampnum)
    {
        int i;
        int cnt = 0; 
        if(global_end_flag == 1 || pos_write == pos_read){return -1}
        memcpy(buf,global_buffer,global_size);
        cnt = global_size/sizeof(SP16);
        pos_write = 0;
        pos_read = 0; 
        //(....) 
        return cnt;
    }
    

    然后:

    boolean
    adin_memory(char* buffer, int size_chunck, int end_flag){
        pos_write += size_chunck;
        global_size = size_chunck;
        global_end_flag = end_flag;
        global_buffer = buffer;
        return TRUE;
    }
    

    【讨论】:

      猜你喜欢
      • 2010-11-11
      • 2017-02-18
      • 1970-01-01
      • 2015-11-19
      • 2014-11-01
      • 2020-03-31
      • 2016-03-15
      • 2015-07-25
      • 2018-01-03
      相关资源
      最近更新 更多