Debug和Release结果不一样是怎么回事

时间:2021-12-10 19:00:45
vs2008中,都是在release版本下,“调试”菜单下的“启动调试”和“开始运行(不调试)”的结果不一样是怎么回事呀?请各位大侠帮忙,已经不是第一次碰到了。就是没法解决!

17 个解决方案

#1


开始运行(不调试)
是运行上一次的编译结果,如果这次修改过源文件,也体现不出来。

#2


例如:如果你有内存访问越界,在debug模式下,每块内存前后都有保护字节,就不是大问题,但是如果湿release模式,也许就失败了。

这只是一个例子,这种不同往往意味着你代码中有些未知的bug,这种bug只在特定条件下才触发。从你描述现象中,其实是无法知道具体什么原因的。你需要在两种模式下都调试才知道原因

至于1楼说的,则是不对的,因为只要你修改了源文件,无论哪种模式,都会重新编译的

#3


引用 1 楼 joanlynnlove 的回复:
开始运行(不调试)
是运行上一次的编译结果,如果这次修改过源文件,也体现不出来。


同意

#4


你就用调试按钮就好了

#5


你指的是Start Debugging(F5)和Start without Debugging(Ctrl+F5);
这个应该很清楚吧,一个是以调试运行(可加断点,单步运行),一个是以不调试直接运行

#6


关键是我不加任何断点,F5与Ctrl+F5的结果不一样,Ctrl+F5结果有错误,不是想要的结果!
引用 5 楼 visualeleven 的回复:
你指的是Start Debugging(F5)和Start without Debugging(Ctrl+F5);
这个应该很清楚吧,一个是以调试运行(可加断点,单步运行),一个是以不调试直接运行

#7


可以我修改原代码后重新编译过了呀!
引用 1 楼 joanlynnlove 的回复:
开始运行(不调试)
是运行上一次的编译结果,如果这次修改过源文件,也体现不出来。

#8


我在debug和release版本下分别用“启动调试”与“开始执行”,得到一样的结论:启动调试和开始执行结果不一样
引用 2 楼 arong1234 的回复:
例如:如果你有内存访问越界,在debug模式下,每块内存前后都有保护字节,就不是大问题,但是如果湿release模式,也许就失败了。

这只是一个例子,这种不同往往意味着你代码中有些未知的bug,这种bug只在特定条件下才触发。从你描述现象中,其实是无法知道具体什么原因的。你需要在两种模式下都调试才知道原因

至于1楼说的,则是不对的,因为只要你修改了源文件,无论哪种模式,都会重新编译的……

#9


在Release下调试运行变量的值有时是异常的

#10


还是多检查检查你的代码吧,从不一样的结果上下手,不要再纠缠于什么运行方式了,
或者你把怎么不一样的结果说清楚.或者干脆贴代码

#11


现在贴上源代码,希望各位分析下问题出在什么地方
        //计算光流保存到向量velocityFieldX,velocityFieldY:std::vector<float> 类型
        GetOpticalFlowFieldMask(mask,newObjRect,m_curFrame,m_nextFrame,velocityFieldX,velocityFieldY);


        //下面是把向量中的值写到dat文件
FILE* testFile;
char buffer1[65];
CString fileName;
_itoa((int)m_curFrameNum,buffer1,10);
char buffer2[65];
_itoa((int)(trackTemplate.poID),buffer2,10);
CString str = "logP";
fileName = m_resultPath + "\\" + "obj" + buffer2 + "velX" + buffer1 + ".dat";
testFile = fopen(fileName,"w");
for (int i = 0; i < velocityFieldX.size(); i++)
{
//CString str;
//str.Format("the current velocity is: %f",velocityFieldX[i]);
//AfxMessageBox(str);

//AfxMessageBox("reach this place");
//float temp = velocityFieldX[i];
//if (temp<-10000000000 || temp>10000000000)
//{
// AfxMessageBox("exist NAN");
//}
//fprintf(testFile,"%f\n",velocityFieldX[i]);
}
fclose(testFile);

      //在release版本下或者debug版本下,用“启动调试”和“开始执行(不调试)”结果不一样,“开始执行”的结果会出现很多的-1.#QANA0


GetOpticalFlowFieldMasik函数如下:

void GetOpticalFlowFieldMask(std::vector<int> &curMask,CRect &matchRange, IplImage * curImage, IplImage *nextFrame, vector<float> &velocityFieldX, vector<float> &velocityFieldY)
{
velocityFieldX.clear();
velocityFieldY.clear();
int nWidth = curImage->width;
int nHeight = curImage->height;
IplImage * curGrayImage = cvCreateImage(cvSize(curImage->width, curImage->height), IPL_DEPTH_8U, 1);
IplImage * nextGrayImage = cvCreateImage(cvSize(curImage->width, curImage->height), IPL_DEPTH_8U, 1);
IplImage * curGrayRect = cvCreateImage(cvSize(matchRange.Width()+1, matchRange.Height()+1), IPL_DEPTH_8U, 1);
IplImage * nextGrayRect = cvCreateImage(cvSize(matchRange.Width()+1, matchRange.Height()+1), IPL_DEPTH_8U, 1);
IplImage * velocityX = cvCreateImage(cvSize(matchRange.Width()+1, matchRange.Height()+1), IPL_DEPTH_32F, 1);
IplImage * velocityY = cvCreateImage(cvSize(matchRange.Width()+1, matchRange.Height()+1), IPL_DEPTH_32F, 1);
cvCopy(curImage,curGrayImage,NULL);
cvCopy(nextFrame,nextGrayImage,NULL);

curGrayImage->origin = 1;
nextGrayImage->origin = 1;
curGrayRect->origin = 1;
nextGrayRect->origin = 1;
velocityX->origin = 1;
velocityY->origin = 1;

for (int i = 0;i <= matchRange.Width();i++)
{
for (int j = 0;j <= matchRange.Height();j++)
{
int x = i + matchRange.left;
int y = j + matchRange.top;
if ( x >= 0 && x < curGrayImage->width && y >= 0 && y< curGrayImage->height)
{
*(curGrayRect->imageData + j * curGrayRect->widthStep + i) = *(curGrayImage->imageData + y * curGrayImage->widthStep + x);
*(nextGrayRect->imageData + j * nextGrayRect->widthStep + i) = *(nextGrayImage->imageData + y * nextGrayImage->widthStep + x);
}
}
}

//【L-K】
//cvCalcOpticalFlowLK(curGrayRect,nextGrayRect,cvSize(1,1),velocityX, velocityY);

//【H-S】
CvTermCriteria criteria;
criteria.epsilon = 0.1;
criteria.max_iter = 20;
criteria.type = CV_TERMCRIT_EPS;
cvCalcOpticalFlowHS(curGrayRect,nextGrayRect,3, velocityX, velocityY, 0.5, criteria);

//【Block Match】
//cvCalcOpticalFlowBM(curGrayRect,nextGrayRect,cvSize(5, 5), cvSize(1, 1), cvSize(10, 10), 1, velocityX, velocityY);

velocityFieldX.clear();
velocityFieldY.clear();
velocityFieldX.resize((matchRange.Width()+1) * (matchRange.Height()+1), 0);
velocityFieldY.resize((matchRange.Width()+1) * (matchRange.Height()+1), 0);

for(int i = 0;i <= matchRange.Width();i++)
{
for(int j = 0;j <= matchRange.Height();j++)
{
float Value = 0.0; 
int ii = i + matchRange.left;
int jj = j + matchRange.top;
if (curMask[ii+jj*m_imageWidth] == 0) 
{
Value = 0;
velocityFieldX[j * (matchRange.Width()+1) + i] = Value;
velocityFieldY[j * (matchRange.Width()+1) + i] = Value;
}
else
{
Value = ((float*)(velocityX->imageData + j * velocityX->widthStep))[i];
velocityFieldX[j * (matchRange.Width()+1) + i] = Value;
Value = ((float*)(velocityY->imageData + j * velocityY->widthStep))[i];
velocityFieldY[j * (matchRange.Width()+1) + i] = Value;
}
}
}

cvReleaseImage(&curGrayImage);
cvReleaseImage(&nextGrayImage);
cvReleaseImage(&curGrayRect);
cvReleaseImage(&nextGrayRect);
cvReleaseImage(&velocityX);
cvReleaseImage(&velocityY);
}
引用 10 楼 stonewater 的回复:
还是多检查检查你的代码吧,从不一样的结果上下手,不要再纠缠于什么运行方式了,
或者你把怎么不一样的结果说清楚.或者干脆贴代码

#12


Value = ((float*)(velocityX->imageData + j * velocityX->widthStep))[i];

velocityX->imageData是什么指针类型,要不是float型的或sizeof和float不一样大的话,就有问题了

#13


Value = ((float*)(velocityX->imageData + j * velocityX->widthStep))[i];

改为下面试试
float *data = (float*)velocityX->imageData;
Value = data[j * velocityX->widthStep +i];

#14


上面错了
float *data = (float*)velocityX->imageData;
Value = data[j * velocityX->widthStep/sizeof(float) +i];

#15


顶下~

#16


最近我也遇到同样的问题:用了别人的三态树控件,一会出来没有复选框的树,一会又有了复选框,郁闷。

#17


似乎找到了答案:

“直接F5生成的release 结果是对的 但是我关掉以后从文件夹打开,结果又不对了 ” 
这主要是你的应用程序运行过程需要加载一系列的动态链接库(DLL),在VS环境中,已经设置了一些搜索路径,所以调试时可以找到他们。而你在文件夹双击的时候,如果程序需要某DLL,就会在当前目录、系统目录查找,如果都找不到的话,自然无法运行了^_^

通常有2类解决方法:
一、 动态链接MFC库,将DLL一同发布出去
1.1 手工方法
 通过VS的命令提示符环境中的dumpbin.exe查看你的主输出文件(××.exe)运行依赖于哪些DLL,手工把他们找出来,和你的exe放在同一个目录下,转移到其他机器的时候整个目录拷贝过去。
1.2 使用安装工具
 最便捷的就是VS内置的发布工具了。
 在VS中“新建项目”-“其他项目类型”-“安装和部署”-“安装向导”,按照提示设置一下。当你选取需要发布的应用程序项目时,一旦找到其“主输出”(对应××.exe),向导会自动搜索出依赖的DLL。
 编译这个“安装项目”后,生成了*.msi文件,以后直接运行它就可以进行安装(好像MS Office等专业软件一样^_^)。
 
二、静态链接MFC库
 在解决方案管理器窗口,右击项目名,选“属性”。在“项目默认值”中,找到“MFC的使用”,选“在静态库中使用MFC”。这样就可以把依赖的那些DLL中,需要的函数都静态链接到exe中。最终只要一个exe就可以运行了。
 不过这样静态链接的exe体积会臃肿很多,^_^ 

#1


开始运行(不调试)
是运行上一次的编译结果,如果这次修改过源文件,也体现不出来。

#2


例如:如果你有内存访问越界,在debug模式下,每块内存前后都有保护字节,就不是大问题,但是如果湿release模式,也许就失败了。

这只是一个例子,这种不同往往意味着你代码中有些未知的bug,这种bug只在特定条件下才触发。从你描述现象中,其实是无法知道具体什么原因的。你需要在两种模式下都调试才知道原因

至于1楼说的,则是不对的,因为只要你修改了源文件,无论哪种模式,都会重新编译的

#3


引用 1 楼 joanlynnlove 的回复:
开始运行(不调试)
是运行上一次的编译结果,如果这次修改过源文件,也体现不出来。


同意

#4


你就用调试按钮就好了

#5


你指的是Start Debugging(F5)和Start without Debugging(Ctrl+F5);
这个应该很清楚吧,一个是以调试运行(可加断点,单步运行),一个是以不调试直接运行

#6


关键是我不加任何断点,F5与Ctrl+F5的结果不一样,Ctrl+F5结果有错误,不是想要的结果!
引用 5 楼 visualeleven 的回复:
你指的是Start Debugging(F5)和Start without Debugging(Ctrl+F5);
这个应该很清楚吧,一个是以调试运行(可加断点,单步运行),一个是以不调试直接运行

#7


可以我修改原代码后重新编译过了呀!
引用 1 楼 joanlynnlove 的回复:
开始运行(不调试)
是运行上一次的编译结果,如果这次修改过源文件,也体现不出来。

#8


我在debug和release版本下分别用“启动调试”与“开始执行”,得到一样的结论:启动调试和开始执行结果不一样
引用 2 楼 arong1234 的回复:
例如:如果你有内存访问越界,在debug模式下,每块内存前后都有保护字节,就不是大问题,但是如果湿release模式,也许就失败了。

这只是一个例子,这种不同往往意味着你代码中有些未知的bug,这种bug只在特定条件下才触发。从你描述现象中,其实是无法知道具体什么原因的。你需要在两种模式下都调试才知道原因

至于1楼说的,则是不对的,因为只要你修改了源文件,无论哪种模式,都会重新编译的……

#9


在Release下调试运行变量的值有时是异常的

#10


还是多检查检查你的代码吧,从不一样的结果上下手,不要再纠缠于什么运行方式了,
或者你把怎么不一样的结果说清楚.或者干脆贴代码

#11


现在贴上源代码,希望各位分析下问题出在什么地方
        //计算光流保存到向量velocityFieldX,velocityFieldY:std::vector<float> 类型
        GetOpticalFlowFieldMask(mask,newObjRect,m_curFrame,m_nextFrame,velocityFieldX,velocityFieldY);


        //下面是把向量中的值写到dat文件
FILE* testFile;
char buffer1[65];
CString fileName;
_itoa((int)m_curFrameNum,buffer1,10);
char buffer2[65];
_itoa((int)(trackTemplate.poID),buffer2,10);
CString str = "logP";
fileName = m_resultPath + "\\" + "obj" + buffer2 + "velX" + buffer1 + ".dat";
testFile = fopen(fileName,"w");
for (int i = 0; i < velocityFieldX.size(); i++)
{
//CString str;
//str.Format("the current velocity is: %f",velocityFieldX[i]);
//AfxMessageBox(str);

//AfxMessageBox("reach this place");
//float temp = velocityFieldX[i];
//if (temp<-10000000000 || temp>10000000000)
//{
// AfxMessageBox("exist NAN");
//}
//fprintf(testFile,"%f\n",velocityFieldX[i]);
}
fclose(testFile);

      //在release版本下或者debug版本下,用“启动调试”和“开始执行(不调试)”结果不一样,“开始执行”的结果会出现很多的-1.#QANA0


GetOpticalFlowFieldMasik函数如下:

void GetOpticalFlowFieldMask(std::vector<int> &curMask,CRect &matchRange, IplImage * curImage, IplImage *nextFrame, vector<float> &velocityFieldX, vector<float> &velocityFieldY)
{
velocityFieldX.clear();
velocityFieldY.clear();
int nWidth = curImage->width;
int nHeight = curImage->height;
IplImage * curGrayImage = cvCreateImage(cvSize(curImage->width, curImage->height), IPL_DEPTH_8U, 1);
IplImage * nextGrayImage = cvCreateImage(cvSize(curImage->width, curImage->height), IPL_DEPTH_8U, 1);
IplImage * curGrayRect = cvCreateImage(cvSize(matchRange.Width()+1, matchRange.Height()+1), IPL_DEPTH_8U, 1);
IplImage * nextGrayRect = cvCreateImage(cvSize(matchRange.Width()+1, matchRange.Height()+1), IPL_DEPTH_8U, 1);
IplImage * velocityX = cvCreateImage(cvSize(matchRange.Width()+1, matchRange.Height()+1), IPL_DEPTH_32F, 1);
IplImage * velocityY = cvCreateImage(cvSize(matchRange.Width()+1, matchRange.Height()+1), IPL_DEPTH_32F, 1);
cvCopy(curImage,curGrayImage,NULL);
cvCopy(nextFrame,nextGrayImage,NULL);

curGrayImage->origin = 1;
nextGrayImage->origin = 1;
curGrayRect->origin = 1;
nextGrayRect->origin = 1;
velocityX->origin = 1;
velocityY->origin = 1;

for (int i = 0;i <= matchRange.Width();i++)
{
for (int j = 0;j <= matchRange.Height();j++)
{
int x = i + matchRange.left;
int y = j + matchRange.top;
if ( x >= 0 && x < curGrayImage->width && y >= 0 && y< curGrayImage->height)
{
*(curGrayRect->imageData + j * curGrayRect->widthStep + i) = *(curGrayImage->imageData + y * curGrayImage->widthStep + x);
*(nextGrayRect->imageData + j * nextGrayRect->widthStep + i) = *(nextGrayImage->imageData + y * nextGrayImage->widthStep + x);
}
}
}

//【L-K】
//cvCalcOpticalFlowLK(curGrayRect,nextGrayRect,cvSize(1,1),velocityX, velocityY);

//【H-S】
CvTermCriteria criteria;
criteria.epsilon = 0.1;
criteria.max_iter = 20;
criteria.type = CV_TERMCRIT_EPS;
cvCalcOpticalFlowHS(curGrayRect,nextGrayRect,3, velocityX, velocityY, 0.5, criteria);

//【Block Match】
//cvCalcOpticalFlowBM(curGrayRect,nextGrayRect,cvSize(5, 5), cvSize(1, 1), cvSize(10, 10), 1, velocityX, velocityY);

velocityFieldX.clear();
velocityFieldY.clear();
velocityFieldX.resize((matchRange.Width()+1) * (matchRange.Height()+1), 0);
velocityFieldY.resize((matchRange.Width()+1) * (matchRange.Height()+1), 0);

for(int i = 0;i <= matchRange.Width();i++)
{
for(int j = 0;j <= matchRange.Height();j++)
{
float Value = 0.0; 
int ii = i + matchRange.left;
int jj = j + matchRange.top;
if (curMask[ii+jj*m_imageWidth] == 0) 
{
Value = 0;
velocityFieldX[j * (matchRange.Width()+1) + i] = Value;
velocityFieldY[j * (matchRange.Width()+1) + i] = Value;
}
else
{
Value = ((float*)(velocityX->imageData + j * velocityX->widthStep))[i];
velocityFieldX[j * (matchRange.Width()+1) + i] = Value;
Value = ((float*)(velocityY->imageData + j * velocityY->widthStep))[i];
velocityFieldY[j * (matchRange.Width()+1) + i] = Value;
}
}
}

cvReleaseImage(&curGrayImage);
cvReleaseImage(&nextGrayImage);
cvReleaseImage(&curGrayRect);
cvReleaseImage(&nextGrayRect);
cvReleaseImage(&velocityX);
cvReleaseImage(&velocityY);
}
引用 10 楼 stonewater 的回复:
还是多检查检查你的代码吧,从不一样的结果上下手,不要再纠缠于什么运行方式了,
或者你把怎么不一样的结果说清楚.或者干脆贴代码

#12


Value = ((float*)(velocityX->imageData + j * velocityX->widthStep))[i];

velocityX->imageData是什么指针类型,要不是float型的或sizeof和float不一样大的话,就有问题了

#13


Value = ((float*)(velocityX->imageData + j * velocityX->widthStep))[i];

改为下面试试
float *data = (float*)velocityX->imageData;
Value = data[j * velocityX->widthStep +i];

#14


上面错了
float *data = (float*)velocityX->imageData;
Value = data[j * velocityX->widthStep/sizeof(float) +i];

#15


顶下~

#16


最近我也遇到同样的问题:用了别人的三态树控件,一会出来没有复选框的树,一会又有了复选框,郁闷。

#17


似乎找到了答案:

“直接F5生成的release 结果是对的 但是我关掉以后从文件夹打开,结果又不对了 ” 
这主要是你的应用程序运行过程需要加载一系列的动态链接库(DLL),在VS环境中,已经设置了一些搜索路径,所以调试时可以找到他们。而你在文件夹双击的时候,如果程序需要某DLL,就会在当前目录、系统目录查找,如果都找不到的话,自然无法运行了^_^

通常有2类解决方法:
一、 动态链接MFC库,将DLL一同发布出去
1.1 手工方法
 通过VS的命令提示符环境中的dumpbin.exe查看你的主输出文件(××.exe)运行依赖于哪些DLL,手工把他们找出来,和你的exe放在同一个目录下,转移到其他机器的时候整个目录拷贝过去。
1.2 使用安装工具
 最便捷的就是VS内置的发布工具了。
 在VS中“新建项目”-“其他项目类型”-“安装和部署”-“安装向导”,按照提示设置一下。当你选取需要发布的应用程序项目时,一旦找到其“主输出”(对应××.exe),向导会自动搜索出依赖的DLL。
 编译这个“安装项目”后,生成了*.msi文件,以后直接运行它就可以进行安装(好像MS Office等专业软件一样^_^)。
 
二、静态链接MFC库
 在解决方案管理器窗口,右击项目名,选“属性”。在“项目默认值”中,找到“MFC的使用”,选“在静态库中使用MFC”。这样就可以把依赖的那些DLL中,需要的函数都静态链接到exe中。最终只要一个exe就可以运行了。
 不过这样静态链接的exe体积会臃肿很多,^_^