Проблема с освобождением памяти в коде c ++ из-за неверного указателя - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть простой код, который рассчитывает 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;
}

1 Ответ

2 голосов
/ 28 апреля 2020

Вы освобождаете все безоговорочно:

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

, если isSigned , то image7 и image8 не инициализируются, иначе image5 и image6 не инициализируются, поведение не определено

инициализирует указатель всех тезисов в NULL или если isSigned просто бесплатно image5 и image6 еще только image7 и image8


Вы уверены, что тег C ++ должен не быть C?


Выполнение

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

неуверенно, если аргумент недопустим, число atoi молча возвращает 0, я рекомендую Вы никогда не будете использовать atoi, но strtol или scanf, проверяя их результат

Вы также получите доступ к argv, не проверив сначала argc, если задано недостаточно аргументов, поведение не определено

вы также не проверяете, что смогли открыть файлы, и вы не проверяете fread результат

...