如何使用不同情况的四叉树结构释放图片的所有内存块?

How to free all memory blocks of a picture using quadree structure with different cases?

几周前,我试图实现一个显示四叉树的函数。我目前的问题是关于同样的工作,所以我把这个 link 传递给你所有的上下文:
(我正在使用来自此 post 的一些功能)

四叉树结构:

typedef struct block_image
{
    int allBlack; //boolean
    struct block_image * son[4];
}block_image;
typedef block_image *image;

目前,我正在开发一个函数来释放四叉树的所有内存块。例如,如果四叉树是白色的,则无事可做,因为指向该结构的指针已经为 NULL。如果四叉树是黑色的,我们释放指针并将其设置为 NULL。否则,如果它是合成图片,我们会负责释放不同子项的 space。

总结:returns 图像的所有块到内存。

我当前的节目:

void freeMemory(image myImage)
{
    if(myImage == NULL)
    {
        return;
    }
    else if(myImage->allBlack)
    {
        free(myImage);
        myImage = NULL;
    }
    else
    {
        freeMemory(myImage->son[0]);
        freeMemory(myImage->son[1]);
        freeMemory(myImage->son[2]);
        freeMemory(myImage->son[3]);
    }  
}

但是,我不确定如何检查我的函数。 例如,我决定创建一个白色四叉树和一个黑色四叉树。但是当我用freeMemory fonction和normalDisplay看前后两个四边形的表示时,并没有区别。

printf("\nfreeMemory\n\n");
image white = Build_white();
image black = Build_black();
printf("before\n");
normalDisplay(black);
printf("\n");
printf("after\n");
freeMemory(black);
normalDisplay(black);
printf("\n");
printf("before\n");
normalDisplay(white);
printf("\nafter\n");
freeMemory(white);
normalDisplay(white);   
printf("\n");

结果:

可以看到,记忆前后的显示没有区别

这是最简单的情况,之后它应该也适用于组合图像,例如

有人建议我使用 valgrind,告诉我要使我的程序运行,必须有与 free() 一样多的 malloc()。但我真的不知道如何解释结果(以及它是否真的有用)。

结果(我的变量名不是英文的,所以 affichageNormal == normalDisplay,Rendmemoire == freeMemory 和 Construit_noir == Build_black)

P.S。我还有两个函数 isWhite 和 isBlack 来判断图片是黑色(没有白色元素)还是白色(没有黑色元素):

int isWhite(image myImage)
{
    if(myImage == NULL)
    {
        return 1;
    }
    else if(myImage->allBlack)
    {
        return 0;
    }
    else if(isWhite(myImage->son[0]) && isWhite(myImage->son[1]) && isWhite(myImage->son[2]) && isWhite(myImage->son[3]))
    {
        return 1;
    }
    return 0;
}


int isblack(image myImage)
{
    if(myImage == NULL)
    {
        return 0;
    }
    else if(myImage->allBlack)
    {
        return 1;
    }
    else if(isBlack(myImage->son[0]) && isBlack(myImage->son[1]) && isBlack(myImage->son[2]) && isBlack(myImage->son[3]))
    {
        return 1;
    }
    return 0;
}

可能对函数有用。

编辑: 如有疑问,我还添加了 normalDisplay 的代码:

void normalDisplay(image myImage)
{
    if(myImage == NULL)
    {
        printf("B");
    }
    else if(myImage->allBlack)
    {
        printf("N");
    }
    else
    {
        printf("+");
        normalDisplay(myImage->son[0]);
        normalDispay(myImage->son[1]);
        normalDisplay(myImage->son[2]);
        normalDisplay(myImage->son[3]);
    }
}

从四叉树中释放内存的一种可靠方法是确保您反馈指针不再指向有效内存。由于您当前的 freeMemory 只接受一个 block_image 指针,该函数无法将此信息传回给调用者。

更好的办法是更改其接口,以便通过另一个间接级别提供此功能。

void freeMemory(image *myImage) {
    if (myImage != NULL && *myImage != NULL) {
        int sonSize = sizeof((*myImage)->son) / sizeof((*myImage)->son[0]);
        while (sonSize) freeMemory(&(*myImage)->son[--sonSize]);
        free(*myImage);
        *myImage = NULL;
    }
}

附带说明一下,您的原始 freeMemory 确实存在内存泄漏,但希望您能解决这个问题。

这样,*myImage = NULL 会将此更改传达给调用者。在调用方,它看起来像这样:

puts("\nfreeMemory\n");
image white = Build_white();
image black = Build_black();
puts("before");
normalDisplay(black);
puts("");
puts("after");
freeMemory(&black);
normalDisplay(black);
puts("");
puts("before");
normalDisplay(white);
puts("\nafter");
freeMemory(&white);
normalDisplay(white);
puts("");

有了这个,您的 normalDisplay 将更好地为您提供情况的“图像”。