C++ I';我收到了fopen的内存泄漏,但没有什么是';新';ed或';马洛克';预计起飞时间

C++ I';我收到了fopen的内存泄漏,但没有什么是';新';ed或';马洛克';预计起飞时间,c++,memory,memory-leaks,C++,Memory,Memory Leaks,我正在使用MS VS2010和一个名为Deleaker的插件来发现我可能错过的任何内存泄漏。它告诉我在fopen_s线路上有2个内存泄漏,但我没有在该线路上使用new或malloc。 每隔一次,当它发现一个漏洞时,它的位置就被锁定了,所以我不认为它看到的是错误的线路。有什么建议吗 注意:图像加载很好,我使用的是LibPNG,OPAL是我自己的DLL,图像和图像->数据在应用程序中使用该DLL释放 我希望我提供了足够的信息(不要太多) OPAL_API void LoadPNGImage(常量字符

我正在使用MS VS2010和一个名为Deleaker的插件来发现我可能错过的任何内存泄漏。它告诉我在fopen_s线路上有2个内存泄漏,但我没有在该线路上使用new或malloc。 每隔一次,当它发现一个漏洞时,它的位置就被锁定了,所以我不认为它看到的是错误的线路。有什么建议吗

注意:图像加载很好,我使用的是LibPNG,OPAL是我自己的DLL,图像和图像->数据在应用程序中使用该DLL释放

我希望我提供了足够的信息(不要太多)

OPAL_API void LoadPNGImage(常量字符*文件名,OPAL::GUI::ImageStruct*&图像) { int位深度、颜色类型、交错类型; png_structp png_ptr; png_infop info_ptr; png_uint_32宽度、高度; 无符号字符*行; 无符号整数sig_read=0; 无符号整数x,y; 文件*fp; image=(OPAL::GUI::ImageStruct*)malloc(sizeof(OPAL::GUI::ImageStruct)); memset(image,0,sizeof(OPAL::GUI::ImageStruct)); if(fopen_s(&fp,filename,“rb”)//此处检测到2个内存泄漏(假阳性??) { image=NULL; 返回; } png_ptr=png_create_read_struct(png_LIBPNG_VER_STRING,NULL,NULL); 如果(png_ptr==NULL) { 免费(图像); image=NULL; fclose(fp); 返回; } png_设置_错误_fn(png_ptr,(png_voidp)NULL,(png_错误_ptr)NULL,用户_警告_fn); info_ptr=png_create_info_struct(png_ptr); if(info_ptr==NULL) { 免费(图像); image=NULL; fclose(fp); png_destroy_read_struct(&png_ptr、png_infopp_NULL、png_infopp_NULL); 返回; } png_init_io(png_ptr,fp); png_set_sig_字节(png_ptr,sig_read); png_read_info(png_ptr,info_ptr); png_get_IHDR(png_ptr、info_ptr、宽度、高度、位深度、颜色类型、交错类型、int_p_NULL、int_p_NULL); png_集_包装(png_ptr); 图像->宽度=宽度; 图像->高度=高度; 图像->数据=(无符号字符*)malloc(sizeof(无符号字符)*4*图像->宽度*图像->高度); memset(图像->数据,0,sizeof(无符号字符)*4*图像->宽度*图像->高度); 如果(!图像->数据) { 免费(图像->数据); 免费(图像); image=NULL; fclose(fp); png_destroy_read_struct(&png_ptr、png_infopp_NULL、png_infopp_NULL); 返回; } 行=(无符号字符*)malloc(宽度*4); 如果(!行) { image=NULL; fclose(fp); png_destroy_read_struct(&png_ptr、png_infopp_NULL、png_infopp_NULL); 返回; } 对于(y=0;y<高度;y++) { png_read_行(png_ptr,(unsigned char*)行,png_bytep_NULL); 对于(x=0;x数据[4*((y*宽度)+x)+0]=(无符号字符)行[(3*x)+0]; 图像->数据[4*((y*宽度)+x)+1]=(无符号字符)行[(3*x)+1]; 图像->数据[4*((y*宽度)+x)+2]=(无符号字符)行[(3*x)+2]; 图像->数据[4*((y*宽度)+x)+3]=(无符号字符)255; 打破 案例PNG\U颜色\U类型\U RGBA: 图像->数据[(4*((y*宽度)+x))+0]=(无符号字符)行[(4*x)+0]; 图像->数据[(4*((y*宽度)+x))+1]=(无符号字符)行[(4*x)+1]; 图像->数据[(4*((y*宽度)+x))+2]=(无符号字符)行[(4*x)+2]; 图像->数据[(4*((y*宽度)+x))+3]=(无符号字符)行[(4*x)+3]; 打破 } } } 自由线; png_读取_结束(png_ptr,info_ptr); png_destroy_read_struct(&png_ptr,&info_ptr,png_infopp_NULL); fclose(fp); } 原来是文件名。 当它作为常量字符直接传递时,我不认为我需要清除它*

这是泄漏检测器错误标记我还是我真的需要释放它


函数的调用方式如下:
LoadPNGImage(“images\\tiles00.png”,tiles)

如果
fopen\u s
无法打开文件,则应释放
图像
数组。该工具可能正在报告泄漏,但行号稍有偏离。解决方法很简单:

    if (fopen_s(&fp, filename, "rb")) {
        free(image);
        image = NULL;
        return;
    }
更多问题:

  • 为什么不使用
    calloc
    而不是
    malloc
    并删除对
    memset
    的调用
  • 为什么不测试内存分配失败
  • 如果出现
    png\u create\u info\u struct
    和类似故障,为什么不按与构造相反的顺序释放分配的对象
  • 如果以后内存分配失败,为什么不销毁
    info\u ptr
  • 如果无法分配
    ,则会丢失许多取消分配调用
  • 没有测试通过
    png\u read\u行读取图像数据失败
以这种方式进行的错误处理非常繁琐且容易出错。您应该使用C++范例,例如RAII,或者使用一个常见的错误处理点,检查各种对象,分别是“代码>空NU/CODE >或<代码> NulLPTR < /Cord>,并按顺序分配它们。
    if (fopen_s(&fp, filename, "rb")) {
        free(image);
        image = NULL;
        return;
    }
int __cdecl _mtinitlocknum (
    int locknum
    )
{
...
        if ( (pcs = _malloc_crt(sizeof(CRITICAL_SECTION))) == NULL ) { <-- HERE!
        errno = ENOMEM;
        return FALSE;
    }
...
            _locktable[locknum].lock = pcs;
void __cdecl _mtdeletelocks(
    void
    )
{
...
    for ( locknum = 0 ; locknum < _TOTAL_LOCKS ; locknum++ ) {
        if ( _locktable[locknum].lock != NULL &&
             _locktable[locknum].kind != lkPrealloc )
...
            _free_crt(pcs);