由于指针无效而在 C++ 代码中释放内存的问题

Problem with freeing memory in c++ code due to invalid pointer

我有计算 PSNR 的简单代码。我有两种类型的图像,带有签名和未签名的数据,所以我必须在我的代码中涵盖这两种情况。现在,当我 运行 代码时,我打印了正确的 PSNR 值,但是我收到以下错误:

munmap_chunk(): 无效指针

已中止(核心已转储)

我知道它有指针。如果有人能指出问题所在,我将不胜感激,这样我就可以进一步探索更多细节。而且,在这种特殊情况下,最好的解决方案是什么?代码如下。

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <math.h>
#include "string.h"
#include <fstream>


int main(int argc, char *argv[])
{
    int i, w, h, t, b; 
    double mse, d, psnr;
    bool isSigned;
    FILE    *in_file1, *in_file2;

    int *image5;
    int *image6;
    unsigned int *image7;
    unsigned int *image8;

    if(argc!=7){
        printf("Usage: %s file1 file2 width height bit_resolution is_signed\n",argv[0]);
        exit(1);
    }

    in_file1=fopen(argv[1],"rb");
    in_file2=fopen(argv[2],"rb");
    w=atoi(argv[3]);
    h=atoi(argv[4]);
    b=atoi(argv[5]);
    isSigned = !strcmp(argv[6], "true");
    t=w*h;


    if (isSigned){
        image5=(int *)calloc(t, sizeof(int));
        image6=(int *)calloc(t, sizeof(int));

        fread(image5,sizeof(int),w*h,in_file1);
        fread(image6,sizeof(int),w*h,in_file2);
    }
    else{

        image7=(unsigned int *)calloc(t, sizeof(unsigned int));
        image8=(unsigned int *)calloc(t, sizeof(unsigned int));

        fread(image7,sizeof(unsigned int),w*h,in_file1);
        fread(image8,sizeof(unsigned int),w*h,in_file2);
    }


    mse=0.;
    if(isSigned)
    {
        for(i=0;i<t;i++){
            d=(double)image5[i]-(double)image6[i]; 
            mse+=d*d;
        }
    }
    else
    {
        for(i=0;i<t;i++){
            d=(double)image7[i]-(double)image8[i]; 
            mse+=d*d;
        }
    }
    mse=mse/t;

    d=1.;
    for(i=0;i<b;i++) d*=2;
    d-=1.;

    psnr=20*log10(d)-10*log10(mse);

    printf("P=%f MSE=%f PSNR=%fdB\n",d, mse, psnr);

    free(image5);
    free(image6);
    free(image7);
    free(image8);

    return 0;
}

你无条件地释放了所有人:

free(image5);
free(image6);
free(image7);
free(image8);

但是

if (isSigned){
    image5=(int *)calloc(t, sizeof(int));
    image6=(int *)calloc(t, sizeof(int));
    ...
}
else{
    image7=(unsigned int *)calloc(t, sizeof(unsigned int));
    image8=(unsigned int *)calloc(t, sizeof(unsigned int));
     ...
}

if isSigned then image7 and image8 没有初始化,else image5image6 未初始化,行为未定义

将所有这些指针初始化为 NULL 或者如果 isSigned 只是释放 image5image6 else只有 image7image8


你确定标签 C++ 不能是 C 吗?


正在做

w=atoi(argv[3]);
h=atoi(argv[4]);
b=atoi(argv[5]);

不确定,如果参数不是有效数字atoi 静默returns 0,我建议你永远不要使用atoi而是strtolscanf 检查他们的结果

您也可以访问 argv 而无需先检查 argc,如果没有提供足够的参数,则行为未定义

你也没有检查你是否能够打开文件,你也没有检查 fread 结果