564 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			564 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
| /* ========================================================================== */
 | |
| /* === Core/cholmod_memory ================================================== */
 | |
| /* ========================================================================== */
 | |
| 
 | |
| /* -----------------------------------------------------------------------------
 | |
|  * CHOLMOD/Core Module.  Copyright (C) 2005-2006,
 | |
|  * Univ. of Florida.  Author: Timothy A. Davis
 | |
|  * The CHOLMOD/Core Module is licensed under Version 2.1 of the GNU
 | |
|  * Lesser General Public License.  See lesser.txt for a text of the license.
 | |
|  * CHOLMOD is also available under other licenses; contact authors for details.
 | |
|  * http://www.cise.ufl.edu/research/sparse
 | |
|  * -------------------------------------------------------------------------- */
 | |
| 
 | |
| /* Core memory management routines:
 | |
|  *
 | |
|  * Primary routines:
 | |
|  * -----------------
 | |
|  * cholmod_malloc		malloc wrapper
 | |
|  * cholmod_free			free wrapper
 | |
|  *
 | |
|  * Secondary routines:
 | |
|  * -------------------
 | |
|  * cholmod_calloc		calloc wrapper
 | |
|  * cholmod_realloc		realloc wrapper
 | |
|  * cholmod_realloc_multiple	realloc wrapper for multiple objects
 | |
|  *
 | |
|  * The user may make use of these, just like malloc and free.  You can even
 | |
|  * malloc an object and safely free it with cholmod_free, and visa versa
 | |
|  * (except that the memory usage statistics will be corrupted).  These routines
 | |
|  * do differ from malloc and free.  If cholmod_free is given a NULL pointer,
 | |
|  * for example, it does nothing (unlike the ANSI free).  cholmod_realloc does
 | |
|  * not return NULL if given a non-NULL pointer and a nonzero size, even if it
 | |
|  * fails (it sets an error code in Common->status instead).
 | |
|  *
 | |
|  * CHOLMOD keeps track of the amount of memory it has allocated, and so the
 | |
|  * cholmod_free routine includes as a parameter the size of the object being
 | |
|  * freed.  This is only used for memory usage statistics, which are very useful
 | |
|  * in finding memory leaks in your program.  If you, the user of CHOLMOD, pass
 | |
|  * the wrong size, the only consequence is that the memory usage statistics
 | |
|  * will be invalid.  This will causes assertions to fail if CHOLMOD is
 | |
|  * compiled with debugging enabled, but otherwise it will cause no errors.
 | |
|  *
 | |
|  * The cholmod_free_* routines for each CHOLMOD object keep track of the size
 | |
|  * of the blocks they free, so they do not require you to pass their sizes
 | |
|  * as a parameter.
 | |
|  *
 | |
|  * If a block of size zero is requested, these routines allocate a block of
 | |
|  * size one instead.
 | |
|  */
 | |
| 
 | |
| #include "cholmod_internal.h"
 | |
| #include "cholmod_core.h"
 | |
| 
 | |
| /* ========================================================================== */
 | |
| /* === cholmod_add_size_t =================================================== */
 | |
| /* ========================================================================== */
 | |
| 
 | |
| /* Safely compute a+b, and check for integer overflow.  If overflow occurs,
 | |
|  * return 0 and set OK to FALSE.  Also return 0 if OK is FALSE on input. */
 | |
| 
 | |
| size_t CHOLMOD(add_size_t) (size_t a, size_t b, int *ok)
 | |
| {
 | |
|     size_t s = a + b ;
 | |
|     (*ok) = (*ok) && (s >= a) ;
 | |
|     return ((*ok) ? s : 0) ;
 | |
| }
 | |
| 
 | |
| /* ========================================================================== */
 | |
| /* === cholmod_mult_size_t ================================================== */
 | |
| /* ========================================================================== */
 | |
| 
 | |
| /* Safely compute a*k, where k should be small, and check for integer overflow.
 | |
|  * If overflow occurs, return 0 and set OK to FALSE.  Also return 0 if OK is
 | |
|  * FALSE on input. */
 | |
| 
 | |
| size_t CHOLMOD(mult_size_t) (size_t a, size_t k, int *ok)
 | |
| {
 | |
|     size_t p = 0, s ;
 | |
|     while (*ok)
 | |
|     {
 | |
| 	if (k % 2)
 | |
| 	{
 | |
| 	    p = p + a ;
 | |
| 	    (*ok) = (*ok) && (p >= a) ;
 | |
| 	}
 | |
| 	k = k / 2 ;
 | |
| 	if (!k) return (p) ;
 | |
| 	s = a + a ;
 | |
| 	(*ok) = (*ok) && (s >= a) ;
 | |
| 	a = s ;
 | |
|     }
 | |
|     return (0) ;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* ========================================================================== */
 | |
| /* === cholmod_malloc ======================================================= */
 | |
| /* ========================================================================== */
 | |
| 
 | |
| /* Wrapper around malloc routine.  Allocates space of size MAX(1,n)*size, where
 | |
|  * size is normally a sizeof (...).
 | |
|  *
 | |
|  * This routine, cholmod_calloc, and cholmod_realloc do not set Common->status
 | |
|  * to CHOLMOD_OK on success, so that a sequence of cholmod_malloc's, _calloc's,
 | |
|  * or _realloc's can be used.  If any of them fails, the Common->status will
 | |
|  * hold the most recent error status.
 | |
|  *
 | |
|  * Usage, for a pointer to int:
 | |
|  *
 | |
|  *	p = cholmod_malloc (n, sizeof (int), Common)
 | |
|  *
 | |
|  * Uses a pointer to the malloc routine (or its equivalent) defined in Common.
 | |
|  */
 | |
| 
 | |
| void *CHOLMOD(malloc)	/* returns pointer to the newly malloc'd block */
 | |
| (
 | |
|     /* ---- input ---- */
 | |
|     size_t n,		/* number of items */
 | |
|     size_t size,	/* size of each item */
 | |
|     /* --------------- */
 | |
|     cholmod_common *Common
 | |
| )
 | |
| {
 | |
|     void *p ;
 | |
|     size_t s ;
 | |
|     int ok = TRUE ;
 | |
| 
 | |
|     RETURN_IF_NULL_COMMON (NULL) ;
 | |
|     if (size == 0)
 | |
|     {
 | |
| 	ERROR (CHOLMOD_INVALID, "sizeof(item) must be > 0")  ;
 | |
| 	p = NULL ;
 | |
|     }
 | |
|     else if (n >= (Size_max / size) || n >= Int_max)
 | |
|     {
 | |
| 	/* object is too big to allocate without causing integer overflow */
 | |
| 	ERROR (CHOLMOD_TOO_LARGE, "problem too large") ;
 | |
| 	p = NULL ;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
| 	/* call malloc, or its equivalent */
 | |
| 	s = CHOLMOD(mult_size_t) (MAX (1,n), size, &ok) ;
 | |
| 	p = ok ? ((Common->malloc_memory) (s)) : NULL ;
 | |
| 	if (p == NULL)
 | |
| 	{
 | |
| 	    /* failure: out of memory */
 | |
| 	    ERROR (CHOLMOD_OUT_OF_MEMORY, "out of memory") ;
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 	    /* success: increment the count of objects allocated */
 | |
| 	    Common->malloc_count++ ;
 | |
| 	    Common->memory_inuse += (n * size) ;
 | |
| 	    Common->memory_usage =
 | |
| 		MAX (Common->memory_usage, Common->memory_inuse) ;
 | |
| 	    PRINTM (("cholmod_malloc %p %d cnt: %d inuse %d\n",
 | |
| 		    p, n*size, Common->malloc_count, Common->memory_inuse)) ;
 | |
| 	}
 | |
|     }
 | |
|     return (p) ;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* ========================================================================== */
 | |
| /* === cholmod_free ========================================================= */
 | |
| /* ========================================================================== */
 | |
| 
 | |
| /* Wrapper around free routine.  Returns NULL, which can be assigned to the
 | |
|  * pointer being freed, as in:
 | |
|  *
 | |
|  *	p = cholmod_free (n, sizeof (int), p, Common) ;
 | |
|  *
 | |
|  * In CHOLMOD, the syntax:
 | |
|  *
 | |
|  *	cholmod_free (n, sizeof (int), p, Common) ;
 | |
|  *
 | |
|  * is used if p is a local pointer and the routine is returning shortly.
 | |
|  * Uses a pointer to the free routine (or its equivalent) defined in Common.
 | |
|  * Nothing is freed if the pointer is NULL.
 | |
|  */
 | |
| 
 | |
| void *CHOLMOD(free)	/* always returns NULL */
 | |
| (
 | |
|     /* ---- input ---- */
 | |
|     size_t n,		/* number of items */
 | |
|     size_t size,	/* size of each item */
 | |
|     /* ---- in/out --- */
 | |
|     void *p,		/* block of memory to free */
 | |
|     /* --------------- */
 | |
|     cholmod_common *Common
 | |
| )
 | |
| {
 | |
|     RETURN_IF_NULL_COMMON (NULL) ;
 | |
|     if (p != NULL)
 | |
|     {
 | |
| 	/* only free the object if the pointer is not NULL */
 | |
| 	/* call free, or its equivalent */
 | |
| 	(Common->free_memory) (p) ;
 | |
| 	Common->malloc_count-- ;
 | |
| 	Common->memory_inuse -= (n * size) ;
 | |
| 	PRINTM (("cholmod_free   %p %d cnt: %d inuse %d\n",
 | |
| 		p, n*size, Common->malloc_count, Common->memory_inuse)) ;
 | |
| 	/* This assertion will fail if the user calls cholmod_malloc and
 | |
| 	 * cholmod_free with mismatched memory sizes.  It shouldn't fail
 | |
| 	 * otherwise. */
 | |
| 	ASSERT (IMPLIES (Common->malloc_count == 0, Common->memory_inuse == 0));
 | |
|     }
 | |
|     /* return NULL, and the caller should assign this to p.  This avoids
 | |
|      * freeing the same pointer twice. */
 | |
|     return (NULL) ;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* ========================================================================== */
 | |
| /* === cholmod_calloc ======================================================= */
 | |
| /* ========================================================================== */
 | |
| 
 | |
| /* Wrapper around calloc routine.
 | |
|  *
 | |
|  * Uses a pointer to the calloc routine (or its equivalent) defined in Common.
 | |
|  * This routine is identical to malloc, except that it zeros the newly allocated
 | |
|  * block to zero.
 | |
|  */
 | |
| 
 | |
| void *CHOLMOD(calloc)	/* returns pointer to the newly calloc'd block */
 | |
| (
 | |
|     /* ---- input ---- */
 | |
|     size_t n,		/* number of items */
 | |
|     size_t size,	/* size of each item */
 | |
|     /* --------------- */
 | |
|     cholmod_common *Common
 | |
| )
 | |
| {
 | |
|     void *p ;
 | |
| 
 | |
|     RETURN_IF_NULL_COMMON (NULL) ;
 | |
|     if (size == 0)
 | |
|     {
 | |
| 	ERROR (CHOLMOD_INVALID, "sizeof(item) must be > 0") ;
 | |
| 	p = NULL ;
 | |
|     }
 | |
|     else if (n >= (Size_max / size) || n >= Int_max)
 | |
|     {
 | |
| 	/* object is too big to allocate without causing integer overflow */
 | |
| 	ERROR (CHOLMOD_TOO_LARGE, "problem too large") ;
 | |
| 	p = NULL ;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
| 	/* call calloc, or its equivalent */
 | |
| 	p = (Common->calloc_memory) (MAX (1,n), size) ;
 | |
| 	if (p == NULL)
 | |
| 	{
 | |
| 	    /* failure: out of memory */
 | |
| 	    ERROR (CHOLMOD_OUT_OF_MEMORY, "out of memory") ;
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 	    /* success: increment the count of objects allocated */
 | |
| 	    Common->malloc_count++ ;
 | |
| 	    Common->memory_inuse += (n * size) ;
 | |
| 	    Common->memory_usage =
 | |
| 		MAX (Common->memory_usage, Common->memory_inuse) ;
 | |
| 	    PRINTM (("cholmod_malloc %p %d cnt: %d inuse %d\n",
 | |
| 		    p, n*size, Common->malloc_count, Common->memory_inuse)) ;
 | |
| 	}
 | |
|     }
 | |
|     return (p) ;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* ========================================================================== */
 | |
| /* === cholmod_realloc ====================================================== */
 | |
| /* ========================================================================== */
 | |
| 
 | |
| /* Wrapper around realloc routine.  Given a pointer p to a block of size
 | |
|  * (*n)*size memory, it changes the size of the block pointed to by p to be
 | |
|  * MAX(1,nnew)*size in size.  It may return a pointer different than p.  This
 | |
|  * should be used as (for a pointer to int):
 | |
|  *
 | |
|  *	p = cholmod_realloc (nnew, sizeof (int), p, *n, Common) ;
 | |
|  *
 | |
|  * If p is NULL, this is the same as p = cholmod_malloc (...).
 | |
|  * A size of nnew=0 is treated as nnew=1.
 | |
|  *
 | |
|  * If the realloc fails, p is returned unchanged and Common->status is set
 | |
|  * to CHOLMOD_OUT_OF_MEMORY.  If successful, Common->status is not modified,
 | |
|  * and p is returned (possibly changed) and pointing to a large block of memory.
 | |
|  *
 | |
|  * Uses a pointer to the realloc routine (or its equivalent) defined in Common.
 | |
|  */
 | |
| 
 | |
| void *CHOLMOD(realloc)	/* returns pointer to reallocated block */
 | |
| (
 | |
|     /* ---- input ---- */
 | |
|     size_t nnew,	/* requested # of items in reallocated block */
 | |
|     size_t size,	/* size of each item */
 | |
|     /* ---- in/out --- */
 | |
|     void *p,		/* block of memory to realloc */
 | |
|     size_t *n,		/* current size on input, nnew on output if successful*/
 | |
|     /* --------------- */
 | |
|     cholmod_common *Common
 | |
| )
 | |
| {
 | |
|     size_t nold = (*n) ;
 | |
|     void *pnew ;
 | |
|     size_t s ;
 | |
|     int ok = TRUE ;
 | |
| 
 | |
|     RETURN_IF_NULL_COMMON (NULL) ;
 | |
|     if (size == 0)
 | |
|     {
 | |
| 	ERROR (CHOLMOD_INVALID, "sizeof(item) must be > 0") ;
 | |
| 	p = NULL ;
 | |
|     }
 | |
|     else if (p == NULL)
 | |
|     {
 | |
| 	/* A fresh object is being allocated. */
 | |
| 	PRINT1 (("realloc fresh: %d %d\n", nnew, size)) ;
 | |
| 	p = CHOLMOD(malloc) (nnew, size, Common) ;
 | |
| 	*n = (p == NULL) ? 0 : nnew ;
 | |
|     }
 | |
|     else if (nold == nnew)
 | |
|     {
 | |
| 	/* Nothing to do.  Do not change p or n. */
 | |
| 	PRINT1 (("realloc nothing: %d %d\n", nnew, size)) ;
 | |
|     }
 | |
|     else if (nnew >= (Size_max / size) || nnew >= Int_max)
 | |
|     {
 | |
| 	/* failure: nnew is too big.  Do not change p or n. */
 | |
| 	ERROR (CHOLMOD_TOO_LARGE, "problem too large") ;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
| 	/* The object exists, and is changing to some other nonzero size. */
 | |
| 	/* call realloc, or its equivalent */
 | |
| 	PRINT1 (("realloc : %d to %d, %d\n", nold, nnew, size)) ;
 | |
| 	pnew = NULL ;
 | |
| 
 | |
| 	s = CHOLMOD(mult_size_t) (MAX (1,nnew), size, &ok) ;
 | |
| 	pnew = ok ? ((Common->realloc_memory) (p, s)) : NULL ;
 | |
| 
 | |
| 	if (pnew == NULL)
 | |
| 	{
 | |
| 	    /* Do not change p, since it still points to allocated memory */
 | |
| 	    if (nnew <= nold)
 | |
| 	    {
 | |
| 		/* The attempt to reduce the size of the block from n to
 | |
| 		 * nnew has failed.  The current block is not modified, so
 | |
| 		 * pretend to succeed, but do not change p.  Do change
 | |
| 		 * CHOLMOD's notion of the size of the block, however. */
 | |
| 		*n = nnew ;
 | |
| 		PRINTM (("nnew <= nold failed, pretend to succeed\n")) ;
 | |
| 		PRINTM (("cholmod_free %p %d cnt: %d inuse %d\n"
 | |
| 			 "cholmod_malloc %p %d cnt: %d inuse %d\n",
 | |
| 		    p, nold*size, Common->malloc_count-1,
 | |
| 				  Common->memory_inuse - nold*size,
 | |
| 		    p, nnew*size, Common->malloc_count,
 | |
| 				  Common->memory_inuse + (nnew-nold)*size)) ;
 | |
| 		Common->memory_inuse += ((nnew-nold) * size) ;
 | |
| 	    }
 | |
| 	    else
 | |
| 	    {
 | |
| 		/* Increasing the size of the block has failed.
 | |
| 		 * Do not change n. */
 | |
| 		ERROR (CHOLMOD_OUT_OF_MEMORY, "out of memory") ;
 | |
| 	    }
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 	    /* success: return revised p and change the size of the block */
 | |
| 	    PRINTM (("cholmod_free %p %d cnt: %d inuse %d\n"
 | |
| 		     "cholmod_malloc %p %d cnt: %d inuse %d\n",
 | |
| 		p, nold*size,    Common->malloc_count-1,
 | |
| 				 Common->memory_inuse - nold*size,
 | |
| 		pnew, nnew*size, Common->malloc_count,
 | |
| 				 Common->memory_inuse + (nnew-nold)*size)) ;
 | |
| 	    p = pnew ;
 | |
| 	    *n = nnew ;
 | |
| 	    Common->memory_inuse += ((nnew-nold) * size) ;
 | |
| 	}
 | |
| 	Common->memory_usage = MAX (Common->memory_usage, Common->memory_inuse);
 | |
|     }
 | |
| 
 | |
|     return (p) ;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* ========================================================================== */
 | |
| /* === cholmod_realloc_multiple ============================================= */
 | |
| /* ========================================================================== */
 | |
| 
 | |
| /* reallocate multiple blocks of memory, all of the same size (up to two integer
 | |
|  * and two real blocks).  Either reallocations all succeed, or all are returned
 | |
|  * in the original size (they are freed if the original size is zero).  The nnew
 | |
|  * blocks are of size 1 or more.
 | |
|  */
 | |
| 
 | |
| int CHOLMOD(realloc_multiple)
 | |
| (
 | |
|     /* ---- input ---- */
 | |
|     size_t nnew,	/* requested # of items in reallocated blocks */
 | |
|     int nint,		/* number of int/UF_long blocks */
 | |
|     int xtype,		/* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */
 | |
|     /* ---- in/out --- */
 | |
|     void **I,		/* int or UF_long block */
 | |
|     void **J,		/* int or UF_long block */
 | |
|     void **X,		/* complex or double block */
 | |
|     void **Z,		/* zomplex case only: double block */
 | |
|     size_t *nold_p,	/* current size of the I,J,X,Z blocks on input,
 | |
| 			 * nnew on output if successful */
 | |
|     /* --------------- */
 | |
|     cholmod_common *Common
 | |
| )
 | |
| {
 | |
|     double *xx, *zz ;
 | |
|     size_t i, j, x, z, nold ;
 | |
| 
 | |
|     RETURN_IF_NULL_COMMON (FALSE) ;
 | |
| 
 | |
|     if (xtype < CHOLMOD_PATTERN || xtype > CHOLMOD_ZOMPLEX)
 | |
|     {
 | |
| 	ERROR (CHOLMOD_INVALID, "invalid xtype") ;
 | |
| 	return (FALSE) ;
 | |
|     }
 | |
| 
 | |
|     nold = *nold_p ;
 | |
| 
 | |
|     if (nint < 1 && xtype == CHOLMOD_PATTERN)
 | |
|     {
 | |
| 	/* nothing to do */
 | |
| 	return (TRUE) ;
 | |
|     }
 | |
| 
 | |
|     i = nold ;
 | |
|     j = nold ;
 | |
|     x = nold ;
 | |
|     z = nold ;
 | |
| 
 | |
|     if (nint > 0)
 | |
|     {
 | |
| 	*I = CHOLMOD(realloc) (nnew, sizeof (Int), *I, &i, Common) ;
 | |
|     }
 | |
|     if (nint > 1)
 | |
|     {
 | |
| 	*J = CHOLMOD(realloc) (nnew, sizeof (Int), *J, &j, Common) ;
 | |
|     }
 | |
| 
 | |
|     switch (xtype)
 | |
|     {
 | |
| 	case CHOLMOD_REAL:
 | |
| 	    *X = CHOLMOD(realloc) (nnew, sizeof (double), *X, &x, Common) ;
 | |
| 	    break ;
 | |
| 
 | |
| 	case CHOLMOD_COMPLEX:
 | |
| 	    *X = CHOLMOD(realloc) (nnew, 2*sizeof (double), *X, &x, Common) ;
 | |
| 	    break ;
 | |
| 
 | |
| 	case CHOLMOD_ZOMPLEX:
 | |
| 	    *X = CHOLMOD(realloc) (nnew, sizeof (double), *X, &x, Common) ;
 | |
| 	    *Z = CHOLMOD(realloc) (nnew, sizeof (double), *Z, &z, Common) ;
 | |
| 	    break ;
 | |
|     }
 | |
| 
 | |
|     if (Common->status < CHOLMOD_OK)
 | |
|     {
 | |
| 	/* one or more realloc's failed.  Resize all back down to nold. */
 | |
| 
 | |
| 	if (nold == 0)
 | |
| 	{
 | |
| 
 | |
| 	    if (nint > 0)
 | |
| 	    {
 | |
| 		*I = CHOLMOD(free) (i, sizeof (Int), *I, Common) ;
 | |
| 	    }
 | |
| 	    if (nint > 1)
 | |
| 	    {
 | |
| 		*J = CHOLMOD(free) (j, sizeof (Int), *J, Common) ;
 | |
| 	    }
 | |
| 
 | |
| 	    switch (xtype)
 | |
| 	    {
 | |
| 		case CHOLMOD_REAL:
 | |
| 		    *X = CHOLMOD(free) (x, sizeof (double), *X, Common) ;
 | |
| 		    break ;
 | |
| 
 | |
| 		case CHOLMOD_COMPLEX:
 | |
| 		    *X = CHOLMOD(free) (x, 2*sizeof (double), *X, Common) ;
 | |
| 		    break ;
 | |
| 
 | |
| 		case CHOLMOD_ZOMPLEX:
 | |
| 		    *X = CHOLMOD(free) (x, sizeof (double), *X, Common) ;
 | |
| 		    *Z = CHOLMOD(free) (x, sizeof (double), *Z, Common) ;
 | |
| 		    break ;
 | |
| 	    }
 | |
| 
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 	    if (nint > 0)
 | |
| 	    {
 | |
| 		*I = CHOLMOD(realloc) (nold, sizeof (Int), *I, &i, Common) ;
 | |
| 	    }
 | |
| 	    if (nint > 1)
 | |
| 	    {
 | |
| 		*J = CHOLMOD(realloc) (nold, sizeof (Int), *J, &j, Common) ;
 | |
| 	    }
 | |
| 
 | |
| 	    switch (xtype)
 | |
| 	    {
 | |
| 		case CHOLMOD_REAL:
 | |
| 		    *X = CHOLMOD(realloc) (nold, sizeof (double), *X, &x,
 | |
| 			    Common) ;
 | |
| 		    break ;
 | |
| 
 | |
| 		case CHOLMOD_COMPLEX:
 | |
| 		    *X = CHOLMOD(realloc) (nold, 2*sizeof (double), *X, &x,
 | |
| 			    Common) ;
 | |
| 		    break ;
 | |
| 
 | |
| 		case CHOLMOD_ZOMPLEX:
 | |
| 		    *X = CHOLMOD(realloc) (nold, sizeof (double), *X, &x,
 | |
| 			    Common) ;
 | |
| 		    *Z = CHOLMOD(realloc) (nold, sizeof (double), *Z, &z,
 | |
| 			    Common) ;
 | |
| 		    break ;
 | |
| 	    }
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	return (FALSE) ;
 | |
|     }
 | |
| 
 | |
|     if (nold == 0)
 | |
|     {
 | |
| 	/* New space was allocated.  Clear the first entry so that valgrind
 | |
| 	 * doesn't complain about its access in change_complexity
 | |
| 	 * (Core/cholmod_complex.c). */
 | |
| 	xx = *X ;
 | |
| 	zz = *Z ;
 | |
| 	switch (xtype)
 | |
| 	{
 | |
| 	    case CHOLMOD_REAL:
 | |
| 		xx [0] = 0 ;
 | |
| 		break ;
 | |
| 
 | |
| 	    case CHOLMOD_COMPLEX:
 | |
| 		xx [0] = 0 ;
 | |
| 		xx [1] = 0 ;
 | |
| 		break ;
 | |
| 
 | |
| 	    case CHOLMOD_ZOMPLEX:
 | |
| 		xx [0] = 0 ;
 | |
| 		zz [0] = 0 ;
 | |
| 		break ;
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     /* all realloc's succeeded, change size to reflect realloc'ed size. */
 | |
|     *nold_p = nnew ;
 | |
|     return (TRUE) ;
 | |
| }
 |