示例

以下是来自 概述 小节的示例,经过重写以使 I/O 缓冲区是通过使用第一个函数集从 Python 堆中分配的:

  1. PyObject *res;
  2. char *buf = (char *) PyMem_Malloc(BUFSIZ); /* for I/O */
  3. if (buf == NULL)
  4. return PyErr_NoMemory();
  5. /* ...Do some I/O operation involving buf... */
  6. res = PyBytes_FromString(buf);
  7. PyMem_Free(buf); /* allocated with PyMem_Malloc */
  8. return res;

使用面向类型函数集的相同代码:

  1. PyObject *res;
  2. char *buf = PyMem_New(char, BUFSIZ); /* for I/O */
  3. if (buf == NULL)
  4. return PyErr_NoMemory();
  5. /* ...Do some I/O operation involving buf... */
  6. res = PyBytes_FromString(buf);
  7. PyMem_Del(buf); /* allocated with PyMem_New */
  8. return res;

请注意在以上两个示例中,缓冲区总是通过归属于相同集的函数来操纵的。 事实上,对于一个给定的内存块必须使用相同的内存 API 族,以便使得混合不同分配器的风险减至最低。 以下代码序列包含两处错误,其中一个被标记为 fatal 因为它混合了两种在不同堆上操作的不同分配器。

  1. char *buf1 = PyMem_New(char, BUFSIZ);
  2. char *buf2 = (char *) malloc(BUFSIZ);
  3. char *buf3 = (char *) PyMem_Malloc(BUFSIZ);
  4. ...
  5. PyMem_Del(buf3); /* Wrong -- should be PyMem_Free() */
  6. free(buf2); /* Right -- allocated via malloc() */
  7. free(buf1); /* Fatal -- should be PyMem_Del() */

除了旨在处理来自 Python 堆的原始内存块的函数之外, Python 中的对象是通过 PyObject_New(), PyObject_NewVar()PyObject_Del() 来分配和释放的。

这些将在有关如何在 C 中定义和实现新对象类型的下一章中讲解。