我在C中为iPhone实现floodfill
功能。
尽管我遇到了2个问题,但填充工作正常。
手机在几次执行下面的代码后发出内存警告。很可能是内存泄漏。另请注意, unsigned char * data (图像数据)在填充结束时是免费的()。
(较小的问题)如果我尝试将 RGB 颜色写入大于的像素(r:200,g:200,b:200,a:200) )我发生了奇怪的瑕疵。解决方法是简单地限制值。
我怀疑这两个问题之间可能存在相关性。
下面的代码描述了我的泛洪填充算法,使用堆栈:
·H
typedef struct {
int red;
int green;
int blue;
int alpha;
} GUIColor;
struct pixel_st {
int x;
int y;
struct pixel_st *nextPixel;
};
typedef struct pixel_st pixel;
.m:
void floodFill(CGPoint location, GUIColor tc, GUIColor rc, size_t width, size_t height, unsigned char *data){
if (isGUIColorEqual(tc, rc)) return;
pixel* aPixel = (pixel *) malloc(sizeof (struct pixel_st));
NSLog(@"sizeof aPixel : %i",(int)sizeof(aPixel));
(*aPixel).x = location.x;
(*aPixel).y = location.y;
(*aPixel).nextPixel = NULL;
int i = 0;
NSLog(@"Replacement color A%i, R%i, G%i, B%i",rc.alpha,rc.red,rc.green, rc.blue);
while (aPixel != NULL){
pixel *oldPixel_p = aPixel;
pixel currentPixel = *aPixel;
aPixel = currentPixel.nextPixel;
//Now we do some boundary checks
if (!isOutOfBounds(currentPixel.x, currentPixel.y, width, height)){
//Grab the current Pixel color
GUIColor currentColor = getGUIColorFromPixelAtLocation(CGPointMake(currentPixel.x, currentPixel.y), width, height, data);
if (isGUIColorSimilar(currentColor, tc)){
//Colors are similar, lets continue the spread
setGUIColorToPixelAtLocation(CGPointMake(currentPixel.x, currentPixel.y), rc, width,height, data);
pixel *newPixel;
if ((newPixel = (pixel*) malloc(sizeof(struct pixel_st))) != NULL) {
(*newPixel).x = currentPixel.x;
(*newPixel).y = currentPixel.y-1;
(*newPixel).nextPixel = aPixel;
aPixel = newPixel;
}
if ((newPixel = (pixel*) malloc(sizeof(struct pixel_st))) != NULL) {
(*newPixel).x = currentPixel.x;
(*newPixel).y = currentPixel.y+1;
(*newPixel).nextPixel = aPixel;
aPixel = newPixel;
}
if ((newPixel = (pixel*) malloc(sizeof(struct pixel_st))) != NULL) {
(*newPixel).x = currentPixel.x+1;
(*newPixel).y = currentPixel.y;
(*newPixel).nextPixel = aPixel;
aPixel = newPixel;
}
if ((newPixel = (pixel*) malloc(sizeof(struct pixel_st))) != NULL) {
(*newPixel).x = currentPixel.x-1;
(*newPixel).y = currentPixel.y;
(*newPixel).nextPixel = aPixel;
aPixel = newPixel;
}
free(oldPixel_p);
i ++;
if (i == width * height * 4 * 5) break;
}
}
}
free(aPixel);
}
该堆栈的实现基于此处的ObjFloodFill
:
https://github.com/OgreSwamp/ObjFloodFill/blob/master/src/FloodFill.m
答案 0 :(得分:1)
首先,循环内的每个if ((newPixel = (pixel*) malloc(...
分配新的内存块,因此,您在循环内部有 4 分配,并且只有 1 解除分配。 / p>
其次,我无法理解你为什么不简单地在堆栈上使用对象?你真的需要在堆上分配 newPixel , oldPixel 等等吗?审查实现,可能有更简单的方法来实现相同的,而不管理内存问题。
答案 1 :(得分:0)
您需要将oldPixel_p
的重新分配移到if
块之外,因为它总是被“消耗”。
此外,最终free
仅释放列表中的第一个元素。该列表可能包含多个元素。您需要逐步浏览列表并释放所有剩余元素。