我在使用C进行图像处理时遇到了释放分配的内存的问题。我正在从文件中加载我的jpeg图像,然后根据图像是否在图像中执行某些操作灰度或RGB。
关键是加载数据的向量将具有以下两种结构之一:
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);
}
答案 0 :(得分:1)
问题在于:
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];
}
当内存malloc'ed被覆盖时,会导致内存泄漏。然后你尝试释放每个oimagen->imgRGB[i][j]
的内存,这不在malloc的块的开头。这会导致未定义的行为,在您的情况下会显示在核心转储中。
这可以通过简单地不在此块中分配任何内存来修复,并且随后不会尝试free
它。
所以上面的循环现在看起来像这样:
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);
}
}