+ -
当前位置:首页 → 问答吧 → 代码运行出现stack overflow

代码运行出现stack overflow

时间:2011-12-01

来源:互联网

以下是我的代码:
C/C++ code
 
   m_imgWidthOut=m_imgWidth;
   m_imgHeightOut=m_imgHeight;
   m_nBitCountOut=m_nBitCount;
   int LineByte=(m_imgWidthOut*m_nBitCount/8+3)/4*4;
   m_pImgDataOut=new unsigned char[m_imgHeightOut*LineByte]; 
   int m_calNum=1;//标记连通域个数
   int m_pixelNum[255];//标记指定连通区域像素数
   int i,j;
   for (i=0;i<m_imgHeightOut;i++)
   {
       for (j=0;j<m_imgWidthOut;j++)
       {
         if (m_pImgDataOut[i*LineByte+j]==255)
           {
               RecursiveCal(m_pImgDataOut,i,j,LineByte,m_pixelNum[m_calNum],m_calNum);
               m_calNum++;
           }
       }
   }
  //如果区域内像素个数小于阈值,则将标志位置零
   for (i=0;i<m_calNum;i++)
   {
       if (m_pixelNum[i]<80)
       {
           m_pixelNum[i]=0;
       }
   }
  //根据标记数组设定图像颜色
 
   for (i=0;i<m_imgHeightOut;i++)
   {
       for (j=0;j<m_imgWidthOut;j++)
       {
           if (m_pImgDataOut[i*LineByte+j]!=0)
           {
               if (m_pixelNum[m_pImgDataOut[i*LineByte+j]]==0)
               {
                   m_pImgDataOut[i*LineByte+j]=0;
               }
               else
               {
                   m_pImgDataOut[i*LineByte+j]=255;
               }
           }
       }
   }
}


void RecursiveCal(unsigned char *pImgData, int y, int x, int lineByte, int &pixelNum, int num)
{
    if (m_pImgData[y*lineByte+x]==255)//报错位置!!!!!!!
    {
        m_pImgData[y*lineByte+x]=num;
    
    pixelNum++;
    int tempx,tempy;
    //递归上面的点
    tempx=y-1;
    tempy=x;
    RecursiveCal(pImgData,tempx,tempy,lineByte,pixelNum,num);
    //递归下面的点
    tempx=y+1;
    tempy=x;
    RecursiveCal(pImgData,tempx,tempy,lineByte,pixelNum,num);
    //递归左边的点
    tempx=y;
    tempy=x-1;
    RecursiveCal(pImgData,tempx,tempy,lineByte,pixelNum,num);
    //递归右边的点
    tempx=y;
    tempy=x+1;
    RecursiveCal(pImgData,tempx,tempy,lineByte,pixelNum,num);
    }
}


代码是将一幅二值图像中较小的连通域去掉,保留较大的连通域。但是在运行后进入递归报错:0xC00000FD: Stack overflow, continue后显示Unhandled exception at 0x00413c29 in ImageLab.exe: 0xC0000005: Access violation writing location 0x00030fc4. 编译没有错误;
查看call stack发现是在递归到第一个区域的像素数为3000多,119行105列时出错。
个人认为递归时由于将白色的像素点都置为了num(这一句:m_pImgData[y*lineByte+x]=num;),所以在没有255时递归会自动结束,但是不知道这么想对不对,还请各位指教啊!

作者: zc3950   发布时间: 2011-12-01

你的num如果等于255,会无限递归导致栈溢出。

作者: ndy_w   发布时间: 2011-12-01

递归上面->递归下面->上面->下面...
已经处理过的不要递归了,需要另外一个数组来存储处理标志。

作者: ndy_w   发布时间: 2011-12-01

引用 1 楼 ndy_w 的回复:

你的num如果等于255,会无限递归导致栈溢出。

我的测试图没有那么多连通区域,所以num不可能等于255;而且已经处理过的置为了num,也不会重复递归吧。。。。

作者: zc3950   发布时间: 2011-12-01

if (m_pImgData[y*lineByte+x]==255)//报错位置!!!!!!!
  {
  m_pImgData[y*lineByte+x]=num;
   
  pixelNum++;
  int tempx,tempy;
  //递归上面的点
  tempx=y-1;
  tempy=x;
  RecursiveCal(pImgData,tempx,tempy,lineByte,pixelNum,num);

就那这个来说,当Y-1 一直这样减下去为-1时,你的pImgData还能有值吗??
判断不准确导致的数组越界!!!

作者: shen_wei   发布时间: 2011-12-01

引用 4 楼 shen_wei 的回复:

if (m_pImgData[y*lineByte+x]==255)//报错位置!!!!!!!
{
m_pImgData[y*lineByte+x]=num;

pixelNum++;
int tempx,tempy;
//递归上面的点
tempx=y-1;
tempy=x;
RecursiveCa……

有道理,如果是图像边缘的点确实有这个问题,但是我刚刚检查了一下我的图,没有边缘为255的点,除了边缘的点的情况下,一旦Y-1点像素不为255,递归应该会跳出,Y-1不可能为负数,可为什么还会溢出呢?。。。。
依然多谢,我也会继续检查我的代码!

作者: zc3950   发布时间: 2011-12-01

看了其他一些文章,导致stack overflow的原因有一项是递归调用太深,我是新手,请教各位太深是深到什么程度啊?我的属于这个问题吗?如果是怎样解决呢?不胜感激!!!

作者: zc3950   发布时间: 2011-12-01