#
9.3 Examples

Here is the example from section 9.1, rewritten so that the I/O buffer is allocated from the Python heap by using the first function set:

          PyObject *res;
          char *buf = (char *) PyMem_Malloc(BUFSIZ); /* for I/O */

          if (buf == NULL)
              return PyErr_NoMemory();
          /* ...Do some I/O operation involving buf... */
          res = PyString_FromString(buf);
          PyMem_Free(buf); /* allocated with PyMem_Malloc */
          return res;

With the second function set, the need to call `PyErr_NoMemory()` is obviated:

          PyObject *res;
          char *buf = (char *) Py_Malloc(BUFSIZ); /* for I/O */

          if (buf == NULL)
              return NULL;
          /* ...Do some I/O operation involving buf... */
          res = PyString_FromString(buf);
          Py_Free(buf); /* allocated with Py_Malloc */
          return res;

The same code using the macro set:

          PyObject *res;
          char *buf = PyMem_NEW(char, BUFSIZ); /* for I/O */

          if (buf == NULL)
              return PyErr_NoMemory();
          /* ...Do some I/O operation involving buf... */
          res = PyString_FromString(buf);
          PyMem_DEL(buf); /* allocated with PyMem_NEW */
          return res;

Note that in the three examples above, the buffer is always manipulated via functions/macros belonging to the same set. Indeed, it is required to use the same memory API family for a given memory block, so that the risk of mixing different allocators is reduced to a minimum. The following code sequence contains two errors, one of which is labeled as fatal because it mixes two different allocators operating on different heaps.

      char *buf1 = PyMem_NEW(char, BUFSIZ);
      char *buf2 = (char *) malloc(BUFSIZ);
      char *buf3 = (char *) PyMem_Malloc(BUFSIZ);
      ...
      PyMem_DEL(buf3);  /* Wrong -- should be PyMem_Free() */
      free(buf2);       /* Right -- allocated via malloc() */
      free(buf1);       /* Fatal -- should be PyMem_DEL()  */

In addition to the functions aimed at handling raw memory blocks from the Python heap, objects in Python are allocated and released with `_PyObject_New()` and `_PyObject_NewVar()`, or with their corresponding macros `PyObject_NEW()` and `PyObject_NEW_VAR()`.