Thread: very weird problem (pointers I think)

  1. #1
    Registered User
    Join Date
    Feb 2005
    Posts
    61

    very weird problem (pointers I think)

    I have a very weird problem with a piece of code I've written. I have been searching and debugging for three days now, and I still haven't found it. Unfortunately, I don't known where exactly the error is located (I know it is in area.c, but not which function etc...). So I don't really expect that you will look at it for a while, and eventually find it, but I still hope so. This is the problem :

    - these are the most important structures used in the code
    (coordinates are stored relatively : from 0 -> 1)
    Code:
    typedef struct Area{
    	struct Area *prev, *next;
    
    	int handle;
    
    	struct AreaEdge *top;
    	struct AreaEdge *left;
    	struct AreaEdge *bottom;
    	struct AreaEdge *right;
    }Area;
    
    //things to know : 
    //area1 : upper or left area
    //area2 : down or right area
    //point1 : upper or left areaPoint
    //point2 : down or right areaPoint
    typedef struct AreaEdge{
    	struct AreaEdge *prev, *next;
    
    	struct Area *area1;
    	struct Area *area2;
    	struct AreaPoint *point1;
    	struct AreaPoint *point2;
    
    	int direction;
    }AreaEdge;
    
    #define GUI_HORIZONTAL	0
    #define GUI_VERTICAL	1
    
    typedef struct AreaPoint{
    	struct AreaPoint *prev, *next;
    
    	float x;
    	float y;
    }AreaPoint;
    - first of all : during initialisation, this is called :
    Code:
    addDefaultArea(s);
    (see last block of code)
    - situation : I have a default area
    4 areaPoints, 4 areaEdges and 1 area (linked to eachother well)

    - I made a splitArea funtion which splits the area where the usere clicks with the left mouse button :
    (ev->val1 and ev->val2 are the coordinates of the mouseclick)
    Code:
    case GUI_MOUSE_LEFT_DOWN:
    		if (ae = onAreaEdge(ev->val1, ev->val2)){
    			splitAreaWhere(ae, ev->val1, ev->val2);
    			return 0;
    		}
    		else return 1;
    - I'll copy area.c here.
    Code:
    //area
    Area *initArea(){
    	Area *a;
    
    	a = malloc(sizeof(Area));
    
    	a->next = 0;
    	a->prev = 0;
    	a->top = a->bottom = a->left = a->right = 0;
    	a->handle = 0;
    
    	return a;
    }
    
    Area *addArea(Screen *s, AreaEdge *e1, AreaEdge *e2){
    	Area *a;
    	AreaEdge *top, *left, *bottom, *right;
    
    	if (!s) return 0;
    	if (!e1 || !e2) return 0;
    	if (e1->direction != e2->direction) return 0;
    
    	a = initArea();
    	LIST_append(s->area, a);
    
    	a->handle = (int)a;
    
    	if (e1->direction == GUI_HORIZONTAL){
    		if(e1->point1->y > e2->point1->y){
    			bottom = e1;
    			top = e2;
    		}
    		else{
    			bottom = e2;
    			top = e1;
    		}
    		if ( !(left = getAreaEdge(s, top->point1, bottom->point1)) )
    			left = addAreaEdge(s, top->point1, bottom->point1);
    		if ( !(right = getAreaEdge(s, top->point2, bottom->point2)) )
    			right = addAreaEdge(s, top->point2, bottom->point2);
    	}
    	else{
    		if(e1->point1->x > e2->point1->x){
    			right = e1;
    			left = e2;
    		}
    		else{
    			right = e2;
    			left = e1;
    		}
    		if ( !(top = getAreaEdge(s, left->point1, right->point1)) )
    			top = addAreaEdge(s, left->point1, right->point1);
    		if ( !(bottom = getAreaEdge(s, left->point2, right->point2)) )
    			bottom = addAreaEdge(s, left->point2, right->point2);
    	}
    
    	a->top = top;
    	top->area2 = a;
    	a->left = left;
    	left->area2 = a;
    	a->bottom = bottom;
    	bottom->area1 = a;
    	a->right = right;
    	right->area1 = a;
    
    	return a;
    }
    
    void removeArea(Screen *s, Area *a){
    	int index;
    
    	index = LIST_getElemIndex(s->area, a);
    	LIST_removeAt(s->area, index);
    
    	if (a == a->top->area2) a->top->area2 = 0;
    	if (a == a->bottom->area1) a->bottom->area1 = 0;
    	if (a == a->left->area2) a->left->area2 = 0;
    	if (a == a->right->area1) a->right->area1 = 0;
    
    	a->handle = 0;
    
    	freeArea(a);
    }
    
    void freeAreaList(List *l){
    	Area *a;
    
    	while(l->first){
    		a = LIST_removeLast(l);
    		freeArea(a);
    	}
    }
    
    void freeArea(Area *a){
    	free(a);
    }
    
    //areaEdge
    AreaEdge *initAreaEdge(){
    	AreaEdge *ae;
    
    	ae = malloc(sizeof(AreaEdge));
    
    	ae->next = 0;
    	ae->prev = 0;
    
    	ae->point1 = 0;
    	ae->point2 = 0;
    
    	ae->area1 = 0;
    	ae->area2 = 0;
    
    	ae->direction = -1;
    
    	return ae;
    }
    
    AreaEdge *addAreaEdge(Screen *s, AreaPoint *p1, AreaPoint *p2){
    	AreaEdge *a;
    	int dir=0;
    
    	if (!s) return 0;
    	if (!p1 || !p2) return 0;
    
    	if ( (p2->x - p1->x) > 0.0001f ) dir |= 1;
    	if ( (p2->y - p1->y) > 0.0001f ) dir |= 2;
    	if (dir == 0 || dir == 3) return 0;
    	dir--;
    
    	a = initAreaEdge();
    	LIST_append(s->areaEdge, a);
    
    	a->point1 = p1;
    	a->point2 = p2;
    	a->direction = dir;
    
    	return a;
    }
    
    void removeAreaEdge(Screen *s, AreaEdge *ae){
    	int index;
    
    	if (ae->area1 || ae->area2) return;
    
    	index = LIST_getElemIndex(s->areaEdge, ae);
    	LIST_removeAt(s->areaEdge, index);
    
    	ae->point1 = 0;
    	ae->point2 = 0;
    	ae->direction = -1;
    
    	freeAreaEdge(ae);
    }
    
    void freeAreaEdgeList(List *l){
    	AreaEdge *ae;
    
    	while(l->first){
    		ae = LIST_removeLast(l);
    		freeAreaEdge(ae);
    	}
    }
    
    void freeAreaEdge(AreaEdge *ae){
    	free(ae);
    }
    
    AreaEdge *getAreaEdge(Screen *s, AreaPoint *p1, AreaPoint *p2){
    	AreaEdge *t;
    
    	t = s->areaEdge->first;
    	while(t){
    		if (t->point1 == p1 && t->point2 == p2){
    			return t;
    		}
    		else if (t->point1 == p2 && t->point2 == p1){
    			return t;
    		}
    		t = t->next;
    	}
    	return 0;
    }
    
    //areaPoint
    AreaPoint *initAreaPoint(){
    	AreaPoint *ap;
    
    	ap = malloc(sizeof(AreaPoint));
    
    	ap->next = 0;
    	ap->prev = 0;
    
    	ap->x = 0;
    	ap->y = 0;
    
    	return ap;
    }
    
    AreaPoint *addAreaPoint(Screen *s, float x, float y){
    	AreaPoint *p;
    
    	if (!s) return 0;
    
    	p = initAreaPoint();
    	LIST_append(s->areaPoint, p);
    
    	p->x = x;
    	p->y = y;
    
    	return p;
    }
    
    void removeAreaPoint(Screen *s, AreaPoint *ap){
    	AreaEdge *t;
    	int index;
    
    	t = s->areaEdge->first;
    	while(t){
    		if (t->point1 == ap || t->point2 == ap) return;
    		t = t->next;
    	}
    
    	index = LIST_getElemIndex(s->areaPoint, ap);
    	LIST_removeAt(s->areaPoint, index);
    
    	ap->x = 0;
    	ap->y = 0;
    
    	freeAreaPoint(ap);
    }
    
    void freeAreaPointList(List *l){
    	AreaPoint *ae;
    
    	while(l->first){
    		ae = LIST_removeLast(l);
    		freeAreaPoint(ae);
    	}
    }
    
    void freeAreaPoint(AreaPoint *ap){
    	free(ap);
    }
    
    void addDefaultArea(Screen *s){
    	AreaPoint *p1, *p2, *p3, *p4;
    	AreaEdge *e1, *e2, *e3, *e4;
    	Area *a;
    	float x, y;
    
    	x = 0;	y = 0;
    	p1 = addAreaPoint(s, x, y);
    	x = 1;	y = 0;
    	p2 = addAreaPoint(s, x, y);
    	x = 1;	y = 1;
    	p3 = addAreaPoint(s, x, y);
    	x = 0;	y = 1;
    	p4 = addAreaPoint(s, x, y);
    
    	e1 = addAreaEdge(s, p1, p2);
    	e2 = addAreaEdge(s, p2, p3);
    	e3 = addAreaEdge(s, p4, p3);
    	e4 = addAreaEdge(s, p1, p4);
    
    	a = addArea(s, e1, e3);
    }
    
    void splitAreaWhere(AreaEdge *ae, int x, int y){
    	AreaPoint *lb, *rb, *ro, *lo, *newp1, *newp2;
    	AreaEdge *b, *o, *l, *r, *newe1, *newe2, *newe3, *newe4, *newe5;
    	Area *split = 0, *newa1, *newa2;
    	guiEvent *event = 0;
    	float fx, fy, where;
    	int dir, loop_done = 0;
    
    	//1 : omzetten naar relatieve coordinaten
    	fx = (float)x / (float)G->win->x;
    	fy = (float)y / (float)G->win->y;
    
    	dir = ae->direction;
    	
    	//2 : berekenen welke area
    	if (dir == GUI_HORIZONTAL){
    		where = fx;
    		if (fy >= ae->point1->y) split = ae->area2;
    		else split = ae->area1;
    	}
    	else{
    		where = fy;
    		if (fx >= ae->point1->x) split = ae->area2;
    		else split = ae->area1;
    	}
    
    	printf("split : %d\n", split);
    	printf("ae : %d\n", ae);
    
    	lb = split->top->point1;
    	rb = split->top->point2;
    	ro = split->bottom->point2;
    	lo = split->bottom->point1;
    
    	b = split->top;
    	o = split->bottom;
    	l = split->left;
    	r = split->right;
    
    	//3 : de eigenlijke splitsing
    	if (dir == GUI_HORIZONTAL){
    		removeArea(G->curScreen, split);
    
    		removeAreaEdge(G->curScreen, b);
    		removeAreaEdge(G->curScreen, o);
    
    		newp1 = addAreaPoint(G->curScreen, where, l->point1->y);
    		newp2 = addAreaPoint(G->curScreen, where, l->point2->y);
    
    		newe1 = addAreaEdge(G->curScreen, lb, newp1);
    		newe2 = addAreaEdge(G->curScreen, newp1, rb);
    		newe3 = addAreaEdge(G->curScreen, lo, newp2);
    		newe4 = addAreaEdge(G->curScreen, newp2, ro);
    		newe5 = addAreaEdge(G->curScreen, newp1, newp2);
    
    		newa1 = addArea(G->curScreen, newe1, newe3);
    		newa2 = addArea(G->curScreen, newe2, newe4);
    	}
    	else{
    		removeArea(G->curScreen, split);
    
    		removeAreaEdge(G->curScreen, l);
    		removeAreaEdge(G->curScreen, r);
    
    		newp1 = addAreaPoint(G->curScreen, b->point1->x, where);
    		newp2 = addAreaPoint(G->curScreen, b->point2->x, where);
    
    		newe1 = addAreaEdge(G->curScreen, lb, newp1);
    		newe2 = addAreaEdge(G->curScreen, newp1, lo);
    		newe3 = addAreaEdge(G->curScreen, rb, newp2);
    		newe4 = addAreaEdge(G->curScreen, newp2, ro);
    		newe5 = addAreaEdge(G->curScreen, newp1, newp2);
    
    		newa1 = addArea(G->curScreen, newe1, newe3);
    		newa2 = addArea(G->curScreen, newe2, newe4);
    	}
    
    	/*//4 : in loop gaan tot key-up
    	while (!loop_done){
    		loop_done = 1;
    	}
    	//5 :		aanpassen van vensterdata
    	//6 :		update()*/
    	/*printf("areas :\n");
    	LIST_printList(G->curScreen->area);
    	printf("areaEdges :\n");
    	LIST_printList(G->curScreen->areaEdge);
    	printf("areaPoints :\n");
    	LIST_printList(G->curScreen->areaPoint);
    	printf("\n");*/
    }
    
    void joinAreas(AreaEdge *ae){
    }
    
    AreaEdge *onAreaEdge(int x, int y){
    	AreaEdge *a;
    	float fx, fy;
    	float t, b, l, r;
    	float offs = 0.01f;
    
    	fx = (float)x / (float)G->win->x;
    	fy = (float)y / (float)G->win->y;
    
    	a = G->curScreen->areaEdge->first;
    	while (a){
    		t = a->point1->y - offs;
    		b = a->point2->y + offs;
    		l = a->point1->x - offs;
    		r = a->point2->x + offs;
    
    		if (t<=fy && b>=fy && l<=fx && r>=fx) return a;
    		a = a->next;
    	}
    
    	return 0;
    }
    Now the error occurs when I have a similar situation as described here :
    Code:
    1)
    ------------------
    |                |
    |                |
    |                |
    |                |
    |                |
    |                |
    |                |
    ------------------
    2)
    ------------------
    |         |      |
    |         |      |
    |         |      |
    |         |      |
    |         |      |
    |         |      |
    |         |      |
    ------------------
    3)
    ------------------
    |         |      |
    |         |      |
    |         |------|
    |         |      |
    |         |      |
    |         |      |
    |         |      |
    ------------------
    4)
    ------------------
    |         |      |
    |         |      |
    |         |------|
    |         |      |
    |         |------|
    |         |      |
    |         |      |
    ------------------
    This is ofcourse flippable.

    The problem happens inbetween situation 3 and 4, when I have called splitAreaWhere(). It crashes at this line :
    lb = split->top->point1;
    Debugging showed me that split didn't get a value. That is because in the next block, ae->area2 == 0. And this is wrong since ae->area2 shouldn't be NULL.

    Code:
    else{
    		where = fy;
    		if (fx >= ae->point1->x) split = ae->area2;
    		else split = ae->area1;
    	}
    I hope someone has a clue. If this is not clear, or if someone should be interested in this problem, then the complete source can be found here :
    http://users.pandora.be/willem.packet1/Gui.zip

    Thanks in advance,

    Hans
    Last edited by hannibar; 10-10-2005 at 04:58 PM.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    God damn, what a nightmare. Explain in one small paragraph, what you're trying to do. Simply state what you want your program to do, what it does, what it doesn't do that it should, and/or, what it does that it shouldn't.


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    ---
    Join Date
    May 2004
    Posts
    1,379
    I don't known where exactly the error is located
    A debugger should be able to narrow it down a bit more than that.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A problem with pointers
    By vsla in forum C Programming
    Replies: 2
    Last Post: 10-10-2007, 04:14 AM
  2. problem with pointers in strcat
    By Elros in forum C Programming
    Replies: 2
    Last Post: 08-15-2007, 10:54 PM
  3. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  4. Weird problem with sscanf
    By g4j31a5 in forum C++ Programming
    Replies: 17
    Last Post: 10-04-2006, 09:16 PM
  5. Weird mouse problem in XP
    By VirtualAce in forum Game Programming
    Replies: 5
    Last Post: 06-16-2004, 11:47 AM