首页 > 解决方案 > 由于指针无效,在 C++ 代码中释放内存的问题

问题描述

我有计算 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;
}

标签: c++free

解决方案


你无条件地释放一切:

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));
     ...
}

如果isSignedimage7image8未初始化,否则image5image6未初始化,行为未定义

将所有这些指针初始化为 NULL 或者如果isSigned只是免费image5image6否则只有image7image8


您确定标签 C++ 一定不是 C 吗?


正在做

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

不确定,如果参数无效 数字会atoi默默返回 0,我建议您不要使用atoibutstrtolscanf检查它们的结果

如果没有给出足够的参数,您也可以在argv不先检查的情况下访问,则行为未定义argc

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


推荐阅读