{"id":471,"date":"2019-12-25T11:28:26","date_gmt":"2019-12-25T11:28:26","guid":{"rendered":"http:\/\/emacslisp.com\/?p=471"},"modified":"2019-12-25T11:29:17","modified_gmt":"2019-12-25T11:29:17","slug":"python-src-how-pymem_getallocator-and-pymem_setallocator-work","status":"publish","type":"post","link":"http:\/\/emacslisp.com\/?p=471","title":{"rendered":"Python Src &#8211; How PyMem_GetAllocator() and PyMem_SetAllocator() work"},"content":{"rendered":"<p>_PyMem_RawMalloc is calling &#8216;malloc&#8217; to allocate memory and return pointer<br \/>\nso _PyMem_RawMalloc is equal to &#8216;malloc&#8217;<\/p>\n<pre lang=\"c\" line=\"1\">\r\nstatic void *\r\n_PyMem_RawMalloc(void *ctx, size_t size)\r\n{\r\n    \/* PyMem_RawMalloc(0) means malloc(1). Some systems would return NULL\r\n       for malloc(0), which would be treated as an error. Some platforms would\r\n       return a pointer with no memory behind it, which would break pymalloc.\r\n       To solve these problems, allocate an extra byte. *\/\r\n    if (size == 0)\r\n        size = 1;\r\n    return malloc(size);\r\n}\r\n <\/pre>\n<pre lang=\"c\" line=\"1\">\r\ntypedef struct {\r\n    \/* user context passed as the first argument to the 4 functions *\/\r\n    void *ctx;\r\n\r\n    \/* allocate a memory block *\/\r\n    void* (*malloc) (void *ctx, size_t size);\r\n\r\n    \/* allocate a memory block initialized by zeros *\/\r\n    void* (*calloc) (void *ctx, size_t nelem, size_t elsize);\r\n\r\n    \/* allocate or resize a memory block *\/\r\n    void* (*realloc) (void *ctx, void *ptr, size_t new_size);\r\n\r\n    \/* release a memory block *\/\r\n    void (*free) (void *ctx, void *ptr);\r\n} PyMemAllocatorEx;\r\n\r\n#define PYRAW_FUNCS _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree \/\/ this means\r\n\/\/*ctx = NULL and (*malloc) = _PyMem_RawMalloc = malloc function in c\r\n\r\n        PyMemAllocatorEx alloc = {NULL, PYRAW_FUNCS}; \r\n\r\n\/\/ alloc will be assigned to _PyMem_Raw, _PyMem, _PyObject\r\n\/\/ for PyMem_GetAllocator, it will get alloc by domain name and pick up one of allocator _PyMem_Raw, _PyMem, _PyObject\r\n        PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &alloc);\r\n        PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &alloc);\r\n        PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &alloc);\r\nvoid\r\nPyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator)\r\n{\r\n    switch(domain)\r\n    {\r\n    case PYMEM_DOMAIN_RAW: _PyMem_Raw = *allocator; break;\r\n    case PYMEM_DOMAIN_MEM: _PyMem = *allocator; break;\r\n    case PYMEM_DOMAIN_OBJ: _PyObject = *allocator; break;\r\n    \/* ignore unknown domain *\/\r\n    }\r\n}\r\n\r\n<\/pre>\n<p>There are 3 Domains that are PYMEM_DOMAIN_RAW, PYMEM_DOMAIN_MEM, PYMEM_DOMAIN_OBJ<\/p>\n<p>alloc will be assigned to _PyMem_Raw, _PyMem, _PyObject based on 3 Domains.<br \/>\nfor PyMem_GetAllocator, it will get alloc by domain name and pick up one of allocator _PyMem_Raw, _PyMem, _PyObject<\/p>\n","protected":false},"excerpt":{"rendered":"<p>_PyMem_RawMalloc is calling &#8216;malloc&#8217; to allocate memory and return pointer so _PyMem_RawMalloc is equal to &#8216;malloc&#8217; static void * _PyMem_RawMalloc(void *ctx, size_t size) { \/* PyMem_RawMalloc(0) means malloc(1). Some systems would return NULL for malloc(0), which would be treated as an error. Some platforms would return a pointer with no memory behind it, which would [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-471","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"http:\/\/emacslisp.com\/index.php?rest_route=\/wp\/v2\/posts\/471","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/emacslisp.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/emacslisp.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/emacslisp.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/emacslisp.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=471"}],"version-history":[{"count":2,"href":"http:\/\/emacslisp.com\/index.php?rest_route=\/wp\/v2\/posts\/471\/revisions"}],"predecessor-version":[{"id":473,"href":"http:\/\/emacslisp.com\/index.php?rest_route=\/wp\/v2\/posts\/471\/revisions\/473"}],"wp:attachment":[{"href":"http:\/\/emacslisp.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=471"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/emacslisp.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=471"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/emacslisp.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=471"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}