分块导入1.2G图像时GlobalAlloc()出错

时间:2021-05-14 17:23:29
在分块导入这个图像时,第一块内存空间可以成功,第二块分配时就出错了,这是为什么啊?代码如下://获取像素数据的大小(文件总长度-位图文件头的长度-位图信息的长度)
 DWORD dwSize=dwFileLength-sizeof(BITMAPFILEHEADER)-sizeof(BITMAPINFO);

 //Read the image by stocks
  lWidth=bitmapinfo.bmiHeader.biWidth;
  nBitCount=bitmapinfo.bmiHeader.biBitCount;
 LONG lLineByte=WIDTHBYTE(lWidth*nBitCount);


 DWORD dwSize1=lLineByte*10000;
 m_hDIB1=(HGLOBAL)::GlobalAlloc(GMEM_MOVEABLE,dwSize1);
  BYTE* m_pdib1=(BYTE*)::GlobalLock((HGLOBAL)m_hDIB1);
 DWORD dwReadSize1=dibFile.Read((void*)m_pdib1,dwSize1);

  DWORD dwSize2=lLineByte*10000;
 m_hDIB2=(HGLOBAL)::GlobalAlloc(GMEM_MOVEABLE,dwSize2);
  BYTE* m_pdib2=(BYTE*)::GlobalLock((HGLOBAL)m_hDIB2);
 DWORD dwReadSize2=dibFile.Read((void*)m_pdib2,dwSize2);

  DWORD dwSize3=lLineByte*10000;
 m_hDIB3=(HGLOBAL)::GlobalAlloc(GMEM_MOVEABLE,dwSize3);
  BYTE* m_pdib3=(BYTE*)::GlobalLock((HGLOBAL)m_hDIB3);
 DWORD dwReadSize3=dibFile.Read((void*)m_pdib3,dwSize3);

  DWORD dwSize4=dwSize-lLineByte*30000;
 m_hDIB4=(HGLOBAL)::GlobalAlloc(GMEM_MOVEABLE,dwSize4);
  BYTE* m_pdib4=(BYTE*)::GlobalLock((HGLOBAL)m_hDIB4);
 DWORD dwReadSize4=dibFile.Read((void*)m_pdib4,dwSize4);
Once——8  17:49:54
//打开对话框,并获得要打开的位图的路径,保存在m_fileName中
static char szFilter[]="位图文件(*.bmp;*.dib)|*.bmp;*.dib|All Files(*.*)|*.*||";
CFileDialog dlg(true,"*.bmp",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter);
if(dlg.DoModal()==IDOK)
{
UpdateData(true);
m_fileName=dlg.GetPathName();
}
//新建CFile类对象dibFile,并用只读的模式打开位图文件
CFile dibFile;
if(!dibFile.Open(m_fileName,CFile::modeRead))
{
 AfxMessageBox("Can't open DIB file...");
 return;
}
//新建一个位图文件头变量
BITMAPFILEHEADER bitmapFileHeader;
//从位图文件中读取与位图文件头大小的字节到文件头变量中
UINT bitmapFileHeaderSize=dibFile.Read((void*)&bitmapFileHeader,sizeof(BITMAPFILEHEADER));
if(bitmapFileHeaderSize!=sizeof(BITMAPFILEHEADER))
{
 AfxMessageBox("读取文件头失败");
 return;
}
//判断读取的文件是否为位图文件
if(bitmapFileHeader.bfType==0x4d42)
{
 //获取整个位图文件的长度
 DWORD dwFileLength=dibFile.GetLength();
 //read bmp info 
 BITMAPINFO bitmapinfo;
 UINT bitmapinfoSize=dibFile.Read((void*)&bitmapinfo,sizeof(BITMAPINFO));
 if(bitmapinfoSize!=sizeof(BITMAPINFO))
 {
  AfxMessageBox("Read BITMAPINFO Fails.");
  return;
 }
//获取像素数据的大小(文件总长度-位图文件头的长度-位图信息的长度)
 DWORD dwSize=dwFileLength-sizeof(BITMAPFILEHEADER)-sizeof(BITMAPINFO);

 //Read the image by stocks
  lWidth=bitmapinfo.bmiHeader.biWidth;
  nBitCount=bitmapinfo.bmiHeader.biBitCount;
 LONG lLineByte=WIDTHBYTE(lWidth*nBitCount);


 DWORD dwSize1=lLineByte*10000;
 m_hDIB1=(HGLOBAL)::GlobalAlloc(GMEM_MOVEABLE,dwSize1);
  BYTE* m_pdib1=(BYTE*)::GlobalLock((HGLOBAL)m_hDIB1);
 DWORD dwReadSize1=dibFile.Read((void*)m_pdib1,dwSize1);//这一块可以分配成功

  DWORD dwSize2=lLineByte*10000;
 m_hDIB2=(HGLOBAL)::GlobalAlloc(GMEM_MOVEABLE,dwSize2);//这里就出错,分配空间失败,m_hDIB2被置为NULL
  BYTE* m_pdib2=(BYTE*)::GlobalLock((HGLOBAL)m_hDIB2);
 DWORD dwReadSize2=dibFile.Read((void*)m_pdib2,dwSize2);

  DWORD dwSize3=lLineByte*10000;
 m_hDIB3=(HGLOBAL)::GlobalAlloc(GMEM_MOVEABLE,dwSize3);
  BYTE* m_pdib3=(BYTE*)::GlobalLock((HGLOBAL)m_hDIB3);
 DWORD dwReadSize3=dibFile.Read((void*)m_pdib3,dwSize3);

  DWORD dwSize4=dwSize-lLineByte*30000;
 m_hDIB4=(HGLOBAL)::GlobalAlloc(GMEM_MOVEABLE,dwSize4);
  BYTE* m_pdib4=(BYTE*)::GlobalLock((HGLOBAL)m_hDIB4);
 DWORD dwReadSize4=dibFile.Read((void*)m_pdib4,dwSize4);

6 个解决方案

#1


其中每个块大致大小为400MB。。。

#2


是不是内存不足?

#3


GlobalAlloc是从堆里分配内存的。一般来说5MB以上的内存分配都不应该从堆里,应该用VirtualAlloc直接分配页来用。堆适合零碎的小段数据,它需要很多额外的cost来管理,效率没有VirtualAlloc高。

#4


引用 2 楼 veron_04 的回复:
是不是内存不足?
是否内存不足该如何查看?我逐步运行时直接在第二个分块处出错。直接返回了NULL。

#5


引用 3 楼 bokutake 的回复:
GlobalAlloc是从堆里分配内存的。一般来说5MB以上的内存分配都不应该从堆里,应该用VirtualAlloc直接分配页来用。堆适合零碎的小段数据,它需要很多额外的cost来管理,效率没有VirtualAlloc高。
如果用VirtualAlloc的话,我第一块的代码该如何更改?能帮我写下吗?我是新手。。。谢谢。。。

#6


GetLastError()就知道为什么出错了。
看看这个:http://blog.csdn.net/long3401/article/details/6366298

#1


其中每个块大致大小为400MB。。。

#2


是不是内存不足?

#3


GlobalAlloc是从堆里分配内存的。一般来说5MB以上的内存分配都不应该从堆里,应该用VirtualAlloc直接分配页来用。堆适合零碎的小段数据,它需要很多额外的cost来管理,效率没有VirtualAlloc高。

#4


引用 2 楼 veron_04 的回复:
是不是内存不足?
是否内存不足该如何查看?我逐步运行时直接在第二个分块处出错。直接返回了NULL。

#5


引用 3 楼 bokutake 的回复:
GlobalAlloc是从堆里分配内存的。一般来说5MB以上的内存分配都不应该从堆里,应该用VirtualAlloc直接分配页来用。堆适合零碎的小段数据,它需要很多额外的cost来管理,效率没有VirtualAlloc高。
如果用VirtualAlloc的话,我第一块的代码该如何更改?能帮我写下吗?我是新手。。。谢谢。。。

#6


GetLastError()就知道为什么出错了。
看看这个:http://blog.csdn.net/long3401/article/details/6366298