gpt4 book ai didi

c - 释放三维矩阵的内存

转载 作者:行者123 更新时间:2023-11-30 15:16:28 26 4
gpt4 key购买 nike

在用 C 进行图像处理时,我在释放分配的内存时遇到问题。我从文件加载 jpeg 图像,然后根据图像是灰度还是 RGB 执行某些操作。

重点是加载数据的 vector 将具有以下两种结构之一:

data { R, G, B, R, G, B, ... }
// OR
data { value, value, value }

这就是我定义结构的方式:

typedef struct {
int width;
int height;
int bytes_per_pixel; /* 3 COLOR o 1 ESCALA DEGRISES */
int color_space; /* JCS_RGB; o JCS_GRAYSCALE */
unsigned char *dat; /* vector de datos de la imagen descomprimida*/
unsigned char **im; /* matriz de punteros para acceder a cada valor de la imagen */
unsigned char *** imgRGB; // [i][j][0] red, [i][j][1] green,[i][j][2] blue
} imagenJPG;

im 字段始终被分配,而 imgRGB 仅当生成的图像为 RGB 时才分配。我用这段代码来做到这一点:

extern void  generar_imagen(imagenJPG *oimagen, int h, int w, int bytesxPixel, unsigned char val)
{
int i, j;
oimagen->width = w;
oimagen->height = h;
oimagen->bytes_per_pixel = bytesxPixel;
if (bytesxPixel == 1)
oimagen->color_space = JCS_GRAYSCALE;
else
oimagen->color_space = JCS_RGB;

/* asignar memoria a la imagen*/

if ((oimagen->dat = (unsigned char *) malloc(w*h * bytesxPixel * sizeof(unsigned char))) == NULL)
{
fprintf(stderr, "Funcion generar_imagen: malloc error\n");
exit(1);
}
/*crear punteros a los pixeles segun el numero de componentes:*/

if ((oimagen->im = (unsigned char **) malloc(h * sizeof(unsigned char *))) == NULL)
{
fprintf(stderr, "Funcion generar_imagen: malloc error\n");
exit(1);
}

for(i = 0; i < h; i++)
oimagen->im[i] = &oimagen->dat[i * w * bytesxPixel];

/* inicializar los pixeles de la imagen*/
memset(oimagen->dat, val, h * w);

if (bytesxPixel == 3)
{
/* para imagenes RGB una matriz de 3 dimensiones*/

if ((oimagen->imgRGB = malloc(h * sizeof(unsigned char **))) == NULL)
{
fprintf(stderr, "Funcion generar_imagen: malloc error\n");
exit(1);
}

for (i = 0; i < h; i++)
{
if ((oimagen->imgRGB[i] = malloc (w * sizeof(unsigned char *))) == NULL)
{
fprintf(stderr, "Funcion generar_imagen: malloc error\n");
exit(1);
}

for (j = 0; j < w; j++) {
if ((oimagen->imgRGB[i][j] = malloc(3 * sizeof(unsigned char ))) == NULL)
{
fprintf(stderr, "Funcion generar_imagen: malloc error\n");
exit(1);
}

oimagen->imgRGB[i][j] = &oimagen->dat[i*w*3+3*j];
}
}


/* inicializar los pixeles de la imagen*/
memset(oimagen->dat, val, h*w*3);
}

}

这样我就可以以二维方式访问图像的每个像素(灰度),并使用第三维(RGB)。当我尝试释放图像时,问题就出现了。这是我尝试过的:(以及许多其他组合)

void  liberar_imagen(imagenJPG iimagen)
{
free(iimagen.dat);
free(iimagen.im);

if (iimagen.bytes_per_pixel==3)
{
int i, j;
for (i = 0; i < iimagen.height; i++) {
for (j = 0; j < iimagen.width; j++) {
free(iimagen.imgRGB[i][j]);
}
free(iimagen.imgRGB[i]);
}
free(iimagen.imgRGB);
}
}

我总是会遇到段错误或双重释放损坏。我能让程序工作的唯一方法是使用这个函数:

void  liberar_imagen(imagenJPG iimagen)
{

free(iimagen.dat);
free(iimagen.im);

if (iimagen.bytes_per_pixel == 3)
{
free(iimagen.imgRGB);
}

}

但不幸的是,这并没有释放所有内存 - 我该怎么办?

编辑:嗯,这就是我现在的方式,它的工作方式就像一个魅力。但是,这是正确的方法吗?:(请注意,我只评论了分配)。

 for (j=0;j<w;j++){

/* if ((oimagen->imgRGB[i][j] =malloc (3* sizeof(unsigned char )))== NULL )
{
fprintf(stderr, "Funcion generar_imagen: malloc error\n");
exit(1);
}*/

oimagen->imgRGB[i][j] = &oimagen->dat[i*w*3+3*j];
}

以及释放内存的函数:

void  liberar_imagen(imagenJPG iimagen)
{
int i;
free(iimagen.dat);
free(iimagen.im);

if (iimagen.bytes_per_pixel==3)
{
for (i=0;i<iimagen.height;i++)
free(iimagen.imgRGB[i]);
}

free(iimagen.imgRGB);

}

最佳答案

问题出在这里:

        for (j = 0; j < w; j++) {
// *** an array of 3 chars is allocated
if ((oimagen->imgRGB[i][j] = malloc(3 * sizeof(unsigned char ))) == NULL)
{
fprintf(stderr, "Funcion generar_imagen: malloc error\n");
exit(1);
}
// *** the pointer to the 3-char array is overwritten with a pointer to dat
oimagen->imgRGB[i][j] = &oimagen->dat[i*w*3+3*j];
}

当内存分配的内存被覆盖时,会导致内存泄漏。然后,您尝试释放每个 oimagen->imgRGB[i][j] 处的内存,该内存不在 malloc block 的开头。这会导致未定义的行为,在您的情况下会在核心转储中体现出来。

只需不在该 block 中分配任何内存,并且随后不尝试释放它即可解决此问题。

所以上面的循环现在看起来像这样:

        for (j = 0; j < w; j++) {
oimagen->imgRGB[i][j] = &oimagen->dat[i*w*3+3*j];
}

你的清理函数将如下所示:

void  liberar_imagen(imagenJPG iimagen)
{
free(iimagen.dat);
free(iimagen.im);

if (iimagen.bytes_per_pixel==3)
{
int i;
for (i = 0; i < iimagen.height; i++) {
free(iimagen.imgRGB[i]);
}
free(iimagen.imgRGB);
}
}

关于c - 释放三维矩阵的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33070731/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com