繁体   English   中英

Visual Studio发行版和调试的区别

[英]Visual Studio Release and Debug difference

我正在编写一个代码,在其中读取和成像并处理它,并获得Mat of double/floatMat of double/float 我将其保存到文件中,然后再从该文件中读取它。

当我使用double时,用于1Kx1K图像所需的空间为8MB,而当使用float时则为4MB。 所以我想用float

这是我的代码和输出:

Mat data = readFloatFile("file_location");
cout << data.at<float>(0,0) << "   " <<  data.at<double>(0,0);

当我在DEBUG mode运行此代码时,float的打印输出为-0并且double给出了异常,即assertion failed 但是当我使用RELEASE mode时,float的打印输出为-0而double的打印输出为0.832,这是真实值

我的问题是,为什么我在使用data.at<float>(0,0)时无法获得输出,为什么data.at<double>(0,0) in RELEASE mode使用data.at<double>(0,0) in RELEASE mode没有得到异常?是这样吗?

编辑 :这是我写和读的代码

void writeNoiseFloat(string imageName,string fingerprintname) throw(){

    Mat noise = getNoise(imageName);

    FILE* fp = fopen(fingerprintname.c_str(),"wb");
    if (!fp){
        cout << "not found ";
        perror("fopen");
    }
    float *buffer = new float[noise.cols];
    for(int i=0;i<noise.rows;++i){
        for(int j=0;j<noise.cols;++j)
            buffer[j]=noise.at<float>(i,j);     
        fwrite(buffer,sizeof(float),noise.cols,fp);
    }

    fclose(fp);
    free(buffer);
}   

void readNoiseFloat(string fpath,Mat& data){
    clock_t start = clock();
    cout << fpath << endl;
    FILE* fp = fopen(fpath.c_str(),"rb");
    if (!fp)perror("fopen");
    int size = 1024;
    data.create(size,size,CV_32F);

    float* buffer= new float[size];
    for(int i=0;i<size;++i)   {
        fread(buffer,sizeof(float),size,fp);
        for(int j=0;j<size;++j){
            data.at<float>(i,j)=buffer[j];
            cout << data.at<float>(i,j) << " " ;
            cout << data.at<double>(i,j);
        }
    }
    fclose(fp);
}

提前致谢,

首先,您不能在一个cv::Mat使用floatdouble ,因为存储本身只是字节数组。 对于float矩阵和double矩阵,此数组的大小将有所不同。

因此,您必须决定要使用什么。

本质上, data.at<type>(x,y)等效于(type*)data_ptr[x][y] (请注意,这不是确切的代码,其目的是显示正在发生的事情)

编辑:在您添加的代码的基础上,您正在创建CV_32F矩阵,这意味着您必须使用float来进行读写和元素。 使用double会导致重新解释价值,并且肯定会给您错误的结果。

关于断言,我确定在cv::MAT::at<class T>有一种以下代码:

assert(sizeof<T>==this.getDepth());

通常,仅在DEBUG模式下编译断言,因此这就是为什么您不在RELEASE给出此错误的原因。

EDIT2:不考虑发布,但切勿将free()new一起使用,或deletemalloc() 结果可能是很难调试的问题。

因此,请使用delete[]作为缓冲区。

调试和发布之间的区别:

您的代码中有一个错误。 它只是没有显示在发布模式下。 这就是调试器的用途。 调试器会告诉您代码中是否有任何错误/问题,Release会一直通过它运行...此外,编译器还会优化您的代码以使其运行更快,因此更小,调试器在HD上使用更大的大小,因为您实际上可以对其进行调试。

Release将未初始化的变量初始化为0。这可能在不同的编译器上有所不同。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM