blob: a02a1e0700c7970793d3580eea76ed3bed008a59 [file] [log] [blame]
Peter Schneider-Kamp25f68942000-07-31 22:19:30 +00001
2/* Lowest-level memory allocation interface */
3
4#ifndef Py_PYMEM_H
5#define Py_PYMEM_H
6
7#include "pyport.h"
8
9#ifdef __cplusplus
10extern "C" {
11#endif
12
13/*
14 * Core memory allocator
15 * =====================
16 */
17
18/* To make sure the interpreter is user-malloc friendly, all memory
19 APIs are implemented on top of this one.
20
21 The PyCore_* macros can be defined to make the interpreter use a
22 custom allocator. Note that they are for internal use only. Both
Neil Schemenauer11f5be82002-03-18 18:13:41 +000023 the core and extension modules should use the PyMem_* API. */
Peter Schneider-Kamp25f68942000-07-31 22:19:30 +000024
25#ifndef PyCore_MALLOC
26#undef PyCore_REALLOC
27#undef PyCore_FREE
Neil Schemenauer11f5be82002-03-18 18:13:41 +000028#define PyCore_MALLOC(n) malloc(n)
29#define PyCore_REALLOC(p, n) realloc((p), (n))
30#define PyCore_FREE(p) free(p)
Peter Schneider-Kamp25f68942000-07-31 22:19:30 +000031#endif
32
33/* BEWARE:
34
35 Each interface exports both functions and macros. Extension modules
36 should normally use the functions for ensuring binary compatibility
37 of the user's code across Python versions. Subsequently, if the
38 Python runtime switches to its own malloc (different from standard
39 malloc), no recompilation is required for the extensions.
40
41 The macro versions trade compatibility for speed. They can be used
42 whenever there is a performance problem, but their use implies
43 recompilation of the code for each new Python release. The Python
44 core uses the macros because it *is* compiled on every upgrade.
45 This might not be the case with 3rd party extensions in a custom
46 setup (for example, a customer does not always have access to the
47 source of 3rd party deliverables). You have been warned! */
48
49/*
50 * Raw memory interface
51 * ====================
52 */
53
54/* Functions */
55
56/* Function wrappers around PyCore_MALLOC and friends; useful if you
57 need to be sure that you are using the same memory allocator as
58 Python. Note that the wrappers make sure that allocating 0 bytes
59 returns a non-NULL pointer, even if the underlying malloc
60 doesn't. Returned pointers must be checked for NULL explicitly.
61 No action is performed on failure. */
62extern DL_IMPORT(void *) PyMem_Malloc(size_t);
63extern DL_IMPORT(void *) PyMem_Realloc(void *, size_t);
64extern DL_IMPORT(void) PyMem_Free(void *);
65
66/* Starting from Python 1.6, the wrappers Py_{Malloc,Realloc,Free} are
67 no longer supported. They used to call PyErr_NoMemory() on failure. */
68
69/* Macros */
70#define PyMem_MALLOC(n) PyCore_MALLOC(n)
71#define PyMem_REALLOC(p, n) PyCore_REALLOC((void *)(p), (n))
72#define PyMem_FREE(p) PyCore_FREE((void *)(p))
73
74/*
75 * Type-oriented memory interface
76 * ==============================
77 */
78
79/* Functions */
80#define PyMem_New(type, n) \
81 ( (type *) PyMem_Malloc((n) * sizeof(type)) )
82#define PyMem_Resize(p, type, n) \
Vladimir Marangozovdcb45c32000-08-13 11:59:08 +000083 ( (p) = (type *) PyMem_Realloc((p), (n) * sizeof(type)) )
Peter Schneider-Kamp25f68942000-07-31 22:19:30 +000084#define PyMem_Del(p) PyMem_Free(p)
85
86/* Macros */
87#define PyMem_NEW(type, n) \
88 ( (type *) PyMem_MALLOC(_PyMem_EXTRA + (n) * sizeof(type)) )
Tim Petersa5d78cc2002-03-02 08:43:19 +000089
90/* See comment near MALLOC_ZERO_RETURNS_NULL in pyport.h. */
91#define PyMem_RESIZE(p, type, n) \
92 do { \
93 size_t _sum = (n) * sizeof(type); \
94 if (!_sum) \
95 _sum = 1; \
96 (p) = (type *)((p) ? \
97 PyMem_REALLOC(p, _sum) : \
98 PyMem_MALLOC(_sum)); \
99 } while (0)
100
Peter Schneider-Kamp25f68942000-07-31 22:19:30 +0000101#define PyMem_DEL(p) PyMem_FREE(p)
102
103/* PyMem_XDEL is deprecated. To avoid the call when p is NULL,
104 it is recommended to write the test explicitly in the code.
105 Note that according to ANSI C, free(NULL) has no effect. */
106
107#ifdef __cplusplus
108}
109#endif
110
Peter Schneider-Kamp25f68942000-07-31 22:19:30 +0000111#endif /* !Py_PYMEM_H */