控制台程序,还没有运行就stack overflow,楼主新手

wangzhihongji 2015-04-28 02:21:01
直接来代码


// myturnimage_original.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
//#include "windows.h"
//#include "mmsystem.h"
#include <atlstr.h>
//#pragma comment(lib,"gdi32")
//#include <stdio.h>

//summary
//把多光谱图像转换成三维数组,再存成图像


BOOL SaveBmp(HBITMAP hBitmap, CString FileName)
{
HDC hDC;
//当前分辨率下每象素所占字节数
int iBits;
//位图中每象素所占字节数
WORD wBitCount;
//定义调色板大小, 位图中像素字节大小 ,位图文件大小 , 写入文件字节数
DWORD dwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0;
//位图属性结构
BITMAP Bitmap;
//位图文件头结构
BITMAPFILEHEADER bmfHdr;
//位图信息头结构
BITMAPINFOHEADER bi;
//指向位图信息头结构
LPBITMAPINFOHEADER lpbi;
//定义文件,分配内存句柄,调色板句柄
HANDLE fh, hDib, hPal,hOldPal=NULL;

//计算位图文件每个像素所占字节数
hDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);
if (iBits <= 1) wBitCount = 1;
else if (iBits <= 4) wBitCount = 4;
else if (iBits <= 8) wBitCount = 8;
else wBitCount = 24;

GetObject(hBitmap, sizeof(Bitmap), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrImportant = 0;
bi.biClrUsed = 0;

dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;

//为位图内容分配内存
hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi;

// 处理调色板
hPal = GetStockObject(DEFAULT_PALETTE);
if (hPal)
{
hDC = ::GetDC(NULL);
hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE);
RealizePalette(hDC);
}

// 获取该调色板下新的像素值
GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
+dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS);

//恢复调色板
if (hOldPal)
{
::SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
RealizePalette(hDC);
::ReleaseDC(NULL, hDC);
}

//创建位图文件
fh = CreateFile(FileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);

if (fh == INVALID_HANDLE_VALUE) return FALSE;

// 设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
// 写入位图文件头
WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
// 写入位图文件其余内容
WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);
//清除
GlobalUnlock(hDib);
GlobalFree(hDib);
CloseHandle(fh);

return TRUE;
}

int _tmain(int argc, _TCHAR* argv[])
{
//initiation
_TCHAR* filename=_T("regenerate_original_picture.txt");
unsigned char data[256];
int packetlen=256;
unsigned short *ImageData[256][256][128];
//What following below is define of the actual argument in the function of "Creat"
HBITMAP hBitmap;
BITMAPINFOHEADER *bmih=NULL ;
BYTE * pBits ;//pBits是内容// 一旦create了,就可以直接操控PB IT s这个指针,
//例如: memset( PB IT s, 0x0, ImageSize ); // 全部变黑或者象下面的
//*( PB IT s + xxxx ) = 255; // 对某个像素赋值.


//填装数据
FILE *pfile=_tfopen(filename,_T("rb"));//rb要用_T转换一下
for (int i = 0; i < 256; i++)
{
fread(data, 1, packetlen, pfile);
//dosomething //pBits,data,memcpy;

}

//CreateDIBitmap创建的是设备相关位图句柄 - HBITMAP.
//CreateDIBSection创建的是设备无关位图句柄 - HBITMAP.




//初始化BITMAPINFOHEADER结构的栏位
bmih->biSize = sizeof (BITMAPINFOHEADER) ;
bmih->biWidth = 384 ;
bmih->biHeight = 256 ;
bmih->biPlanes = 1 ;
bmih->biBitCount = 24 ;
bmih->biCompression = BI_RGB ;
bmih->biSizeImage = 0 ;
bmih->biXPelsPerMeter = 0 ;
bmih->biYPelsPerMeter = 0 ;
bmih->biClrUsed = 0 ;
bmih->biClrImportant = 0 ;
//在基本准备後,我们呼叫该函式:
hBitmap = CreateDIBSection (NULL, (BITMAPINFO *) &bmih, 0, (void**)&pBits, NULL, 0) ;

SaveBmp(hBitmap,"bitmap");
return 0;
}




---------------------------------------------------------问题是

---------------------------------------------------------
完全不知道是怎么回事。。。断点调试并没有什么用,楼主小新手上路,可能范了低级错误却不自知,还请指教。
...全文
156 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
707wk 2015-04-28
  • 打赏
  • 举报
回复
溢出。。。数组过大
wangzhihongji 2015-04-28
  • 打赏
  • 举报
回复
好像是这个问题,顺便复习了一下堆栈问题。。。非常感谢。
赵4老师 2015-04-28
  • 打赏
  • 举报
回复
在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。
youzi05 2015-04-28
  • 打赏
  • 举报
回复
那个时候我测试的,如果写成:

char ch[1000][1000];    // 没事
int a[1000][1000];          // 运行出错
也就是说, 在我的机器上, 栈容不下1M个int型的变量, 而lz的是8M个short !!! 栈肯定溢出啊
youzi05 2015-04-28
  • 打赏
  • 举报
回复
不知道lz这是win32程序还是啥, 没见过_tmain是主方法, 不过,前几个星期, 我同学写了一个程序, 其中有这么一句:

int a[1000][1000];
然后,程序就崩溃了, 和lz的一样, 还没运行... 后来才知道是栈溢出了, 函数中不能有出现太占内存的自动变量, 像lz的这个:

unsigned short *ImageData[256][256][128];
要么弄成全局的, 或者动态分配. 就是说不要占太多栈内存 静态的应该也行, 没试过静态的
此后三年 2015-04-28
  • 打赏
  • 举报
回复
断点在调试中是非常有用的, 在main函数中打个断点,单步执行, 找到执行那一句崩溃,再排查原因。。

64,311

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧