Commits

Jed Brown  committed 78ccc32 Merge

Merge branch 'jed/malloc-zero'

* jed/malloc-zero:
PetscFreeAlign: avoid unshifting NULL
PetscMalloc: allow ptr=malloc(0) and free(ptr)

  • Participants
  • Parent commits 6f717fb, 103af89

Comments (0)

Files changed (3)

File include/petscsys.h

 
    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
 
    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

File src/sys/memory/mal.c

 {
 #if (!(defined(PETSC_HAVE_DOUBLE_ALIGN_MALLOC) && (PETSC_MEMALIGN == 8)) && !defined(PETSC_HAVE_MEMALIGN))
   int shift;
+
+  if (!ptr) PetscFunctionReturn(0);
   /*
        Previous int tells us how many ints the pointer has been shifted from
     the original address provided by the system malloc().

File src/sys/memory/mtr.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);
   }
 
   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);