From 49d7da52b6141b4788dba810f03af76a9b1551d5 Mon Sep 17 00:00:00 2001 From: Jed Brown Date: Wed, 29 Jan 2014 22:31:22 -0700 Subject: [PATCH] PetscMalloc: allow ptr=malloc(0) and free(ptr) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ISO C90 ยง7.10.3: "If the size of the space requested is zero, the behavior is implementation-defined; the value returned shall be either a null pointer or a unique pointer." We believe that ptr=malloc(0) and free(ptr) is now handled properly, so it's no longer necessary to short-circuit our PetscMalloc. This allows memory checking tools to match size-0 allocations and frees if they so choose. --- include/petscsys.h | 14 ++++++++------ src/sys/memory/mtr.c | 7 +------ 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/include/petscsys.h b/include/petscsys.h index d537197bf4a..674ce1e4bff 100644 --- a/include/petscsys.h +++ b/include/petscsys.h @@ -516,17 +516,17 @@ PETSC_EXTERN PetscErrorCode PetscCommDestroy(MPI_Comm*); Level: beginner - Notes: Memory is always allocated at least double aligned + Notes: + Memory is always allocated at least double aligned - If you request memory of zero size it will allocate no space and assign the pointer to 0; PetscFree() will - properly handle not freeing the null pointer. + It is safe to allocate size 0 and pass the resulting pointer (which may or may not be NULL) to PetscFree(). .seealso: PetscFree(), PetscNew() Concepts: memory allocation M*/ -#define PetscMalloc(a,b) ((a != 0) ? (*PetscTrMalloc)((a),__LINE__,PETSC_FUNCTION_NAME,__FILE__,(void**)(b)) : (*(b) = 0,0) ) +#define PetscMalloc(a,b) ((*PetscTrMalloc)((a),__LINE__,PETSC_FUNCTION_NAME,__FILE__,(void**)(b))) /*MC PetscAddrAlign - Rounds up an address to PETSC_MEMALIGN alignment @@ -1072,14 +1072,16 @@ M*/ Level: beginner - Notes: Memory must have been obtained with PetscNew() or PetscMalloc() + Notes: + Memory must have been obtained with PetscNew() or PetscMalloc(). + It is safe to call PetscFree() on a NULL pointer. .seealso: PetscNew(), PetscMalloc(), PetscFreeVoid() Concepts: memory allocation M*/ -#define PetscFree(a) ((a) && ((*PetscTrFree)((void*)(a),__LINE__,PETSC_FUNCTION_NAME,__FILE__) || ((a) = 0,0))) +#define PetscFree(a) ((*PetscTrFree)((void*)(a),__LINE__,PETSC_FUNCTION_NAME,__FILE__) || ((a) = 0,0)) /*MC PetscFreeVoid - Frees memory diff --git a/src/sys/memory/mtr.c b/src/sys/memory/mtr.c index fac91b2df60..05cd3bfb852 100644 --- a/src/sys/memory/mtr.c +++ b/src/sys/memory/mtr.c @@ -176,8 +176,6 @@ PetscErrorCode PetscTrMallocDefault(size_t a,int lineno,const char function[],c PetscErrorCode ierr; PetscFunctionBegin; - if (!a) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to malloc zero size array"); - if (TRdebugLevel) { ierr = PetscMallocValidate(lineno,function,filename); if (ierr) PetscFunctionReturn(ierr); } @@ -257,10 +255,7 @@ PetscErrorCode PetscTrFreeDefault(void *aa,int line,const char function[],const PetscFunctionBegin; /* Do not try to handle empty blocks */ - if (!a) { - (*PetscErrorPrintf)("PetscTrFreeDefault called from %s() line %d in %s\n",function,line,file); - SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to free null block: Free called from %s() line %d in %s\n",function,line,file); - } + if (!a) PetscFunctionReturn(0); if (TRdebugLevel) { ierr = PetscMallocValidate(line,function,file);CHKERRQ(ierr);