首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FreeImage delete[]位图数据失败

FreeImage delete[]位图数据失败
EN

Stack Overflow用户
提问于 2012-09-12 20:04:10
回答 3查看 825关注 0票数 1

请帮我在用FreeImage加载位图后清理我的堆。不知何故,delete[] data;导致了_ASSERTE(_CrtIsValidHeapPointer(pUserData))断言,除了注释这一行之外,我找不到解决它的方法。会不会有内存泄漏?任何帮助和解释都将不胜感激!

完整代码请访问pastebin:http://pastebin.com/dWxz0tjM

Visual Studio2012解决方案(具有巨大的FreeImage静态库):http://rghost.ru/40322357 (15.7MB!)

完整代码如下:

代码语言:javascript
复制
#include <iostream>

// FreeImage static linkage
#define  FREEIMAGE_LIB
#include "FreeImage/FreeImage.h"
#include "FreeImage/Utilities.h"
#pragma comment(lib, "FreeImage/FreeImaged.lib")

using namespace std;

static const wchar_t* sk_Filename = L"Test.tga";

// Error handler to use in callback
void FreeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char *msg) 
{
    char buf[1024];
    sprintf_s(buf, 1024, "Error: %s", FreeImage_GetFormatFromFIF(fif));

    cout << buf;
}


// Bitmap loader from FreeImage samples
FIBITMAP* GenericLoaderU(const wchar_t* lpszPathName, int flag) 
{
    FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;

    fif = FreeImage_GetFileTypeU(lpszPathName, 0);
    if(fif == FIF_UNKNOWN) 
    {
        fif = FreeImage_GetFIFFromFilenameU(lpszPathName);
    }

    if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) 
    {
        FIBITMAP *dib = FreeImage_LoadU(fif, lpszPathName, flag);
        return dib;
    }
    return NULL;
}

// Function gets filename and returns bitmap data array, its size and bits per pixel
void GetData(const wchar_t* szFilename, unsigned char* data, unsigned int& width, unsigned int& height, unsigned int& bpp)
{
    FIBITMAP* src = GenericLoaderU(szFilename, 0);

    if(src == 0)
        return;

    FIBITMAP* src32 = FreeImage_ConvertTo32Bits(src);
    FreeImage_Unload(src);

    // Get picture info
    width = FreeImage_GetWidth(src32);
    height = FreeImage_GetHeight(src32);
    bpp = FreeImage_GetBPP(src32);
    unsigned int scan_width = width * bpp/8;

    if((width == 0) || (height == 0) || (bpp == 0))
        return;


    memset(data, 0, height * scan_width);
    SwapRedBlue32(src32); // Convert BGR to RGB

    // Get bitmap data
    FreeImage_ConvertToRawBits(data, src32, scan_width, bpp, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE);

    FreeImage_Unload(src32);
    return;
}

int main()
{
    FreeImage_Initialise();
    FreeImage_SetOutputMessage(FreeImageErrorHandler);

    //Creating bitmap data array (size is unknown here)
    unsigned char* data = new unsigned char[]; 
    unsigned int width(0), height(0), bpp(0);

    // Loading data here
    GetData(sk_Filename, data, width, height, bpp);

    //Using data here
    cout << width << "x" << height << "x" << bpp << endl;
    for (unsigned int i = 0; i < width * height * bpp/8; )
    {
        cout << "("
        << (unsigned int)data[i] << ", "
        << (unsigned int)data[i+1] << ", "
        << (unsigned int)data[i+2] << ", "
        << (unsigned int)data[i+3] << ")"
        << endl;

        i += 4;
    }
    cout << endl;

    //Cleanup
    delete[] data;  // <-- Breaks with  _ASSERTE(_CrtIsValidHeapPointer(pUserData));
                    // What's wrong here?

    system("pause");

    return 0;
}

-编辑

好的,第一个可能的解决方案是使用std::vector

EN

回答 3

Stack Overflow用户

发布于 2012-11-09 06:40:00

这与delete没有任何关系。

问题是Debug Crt Runtime只能在调用内存API时检查内存完整性,比如: malloc,free,realloc,new,delete。

Crt检测到内存溢出。

显然,new unsigned char[]没有为您分配足够的字节。

将分配移动到GetData()进程中,并像这样调用它:

代码语言:javascript
复制
unsigned char* data = GetData(sk_Filename, width, height, bpp);
票数 1
EN

Stack Overflow用户

发布于 2012-09-12 20:35:49

编写一个根据图像计算数据大小的函数。

然后分配具有该大小的数据

例如:

代码语言:javascript
复制
size_z GetDataSize(const wchar_t* szFilename)
票数 0
EN

Stack Overflow用户

发布于 2012-09-12 21:52:51

GetData函数中很容易计算出所需的大小,所以在那里分配数组并返回它。

你就会有

代码语言:javascript
复制
unsigned char* GetData(const wchar_t* szFilename, 
                       unsigned int& width, 
                       unsigned int& height, 
                       unsigned int& bpp);

它包含

代码语言:javascript
复制
unsigned char* data = new unsigned char[height * scan_width];
// Do the conversion...
return data;

main会说

代码语言:javascript
复制
unsigned char* data = GetData(sk_Filename, width, height, bpp);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12387794

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档