Index: src/hg/lib/liftOver.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/lib/liftOver.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -b -B -U 4 -r1.45 -r1.46
--- src/hg/lib/liftOver.c	24 Jul 2009 20:22:34 -0000	1.45
+++ src/hg/lib/liftOver.c	17 Sep 2009 21:16:20 -0000	1.46
@@ -91,21 +91,27 @@
 return total;
 }
 
 static boolean mapThroughChain(struct chain *chain, double minRatio, 
-                            int *pStart, int *pEnd, struct chain **subChainRet)
+	int *pStart, int *pEnd, struct chain **retSubChain,
+	struct chain **retChainToFree)
 /* Map interval from start to end from target to query side of chain.
  * Return FALSE if not possible, otherwise update *pStart, *pEnd. */
 {
-struct chain *subChain, *freeChain;
+struct chain *subChain = NULL;
+struct chain *freeChain = NULL;
 int s = *pStart, e = *pEnd;
 int oldSize = e - s;
 int newCover = 0;
 int ok = TRUE;
 
 chainSubsetOnT(chain, s, e, &subChain, &freeChain);
 if (subChain == NULL)
+    {
+    *retSubChain = NULL;
+    *retChainToFree = NULL;
     return FALSE;
+    }
 newCover = chainAliSize(subChain);
 if (newCover < oldSize * minRatio)
     ok = FALSE;
 else if (chain->qStrand == '+')
@@ -117,10 +123,10 @@
     {
     *pStart = subChain->qSize - subChain->qEnd;
     *pEnd = subChain->qSize - subChain->qStart;
     }
-*subChainRet = subChain;
-chainFree(&freeChain);
+*retSubChain = subChain;
+*retChainToFree = freeChain;
 return ok;
 }
 
 static char *remapRange(struct hash *chainHash, double minRatio, 
@@ -197,12 +203,16 @@
 /* sort chains by position in target to order subregions by orthology */
 slSort(&chainsHit, chainCmpTarget);
 
 tStart = s;
-for (chain = chainsHit; chain != NULL; chain = chain->next)
+struct chain *next = chainsHit->next;
+for (chain = chainsHit; chain != NULL; chain = next)
     {
     struct chain *subChain = NULL;
+    struct chain *toFree = NULL;
+    struct chain *toFree2 = NULL;
     int start=s, end=e;
+    next = chain->next;
     verbose(3,"hit chain %s:%d %s:%d-%d %c (%d)\n",
         chain->tName, chain->tStart,  chain->qName, chain->qStart, chain->qEnd,
         chain->qStrand, chain->id);
     if (multiple)
@@ -222,15 +232,19 @@
                 chain->tName, chain->tStart,  chain->qName, 
                 chain->qStart, chain->qEnd, chain->qStrand, chain->id);
             }
         }
-    if (!mapThroughChain(chain, minRatio, &start, &end, &subChain))
+    if (!mapThroughChain(chain, minRatio, &start, &end, &subChain, &toFree))
         errAbort("Chain mapping error: %s:%d-%d\n", chain->qName, start, end);
     if (chain->qStrand == '-')
 	strand = otherStrand(strand);
     if (useThick)
-	if (!mapThroughChain(chain, minRatio, &thickStart, &thickEnd, &subChain))
+	{
+	if (!mapThroughChain(chain, minRatio, &thickStart, &thickEnd,
+		&subChain, &toFree2))
 	    thickStart = thickEnd = start;
+	chainFree(&toFree2);
+	}
     verbose(3, "mapped %s:%d-%d\n", chain->qName, start, end);
     verbose(4, "Mapped! Target:\t%s\t%d\t%d\t%c\tQuery:\t%s\t%d\t%d\t%c\n",
 	    chain->tName, subChain->tStart, subChain->tEnd, strand, 
 	    chain->qName, subChain->qStart, subChain->qEnd, chain->qStrand);
@@ -266,8 +280,9 @@
             bed->name = cloneString(regionName);
         slAddHead(&unmappedBedList, bed);
         }
     tStart = subChain->tEnd;
+    chainFree(&toFree);
     }
 slReverse(&bedList);
 *bedRet = bedList;
 slReverse(&unmappedBedList);
@@ -1375,9 +1390,9 @@
 static char *remapBlockedBed(struct hash *chainHash, struct bed *bed)
 /* Remap blocks in bed, and also chromStart/chromEnd.  
  * Return NULL on success, an error string on failure. */
 {
-struct chain *chainList = NULL,  *chain, *subChain, *freeChain;
+struct chain *chainList = NULL,  *chain, *subChain;
 int bedSize = sumBedBlocks(bed);
 struct binElement *binList, *el;
 struct liftRange *rangeList, *badRanges = NULL, *range;
 char *error = NULL;

