I'm writing a Python C extension, and in the examples listed here, there is a snippet of code:
static PyObject * spam_system(PyObject *self, PyObject *args) {
const char *command;
int sts;
if (!PyArg_ParseTuple(args, "s", &command)) return NULL;
sts = system(command);
return Py_BuildValue("i", sts);
}
According to the documentation for parsing a string with PyArg_ParseTuple, "You must not provide storage for the string itself; a pointer to an existing string is stored into the character pointer variable whose address you pass." So how does Python know when the memory pointed to by "command" can be freed? How is a memory leak not occurring?
If free() is not used in a program the memory allocated using malloc() will be de-allocated after completion of the execution of the program (included program execution time is relatively small and the program ends normally).
However on long running programs, failing to free memory means you will be consuming a finite resource without replenishing it. Eventually it will run out and your program will rudely crash. This is why you must free memory.
Objects allocated with new stay on the heap until they are deallocated with delete . If you don't delete them, they will remain there (but won't be accessible -> this is called memory leak) until your process exits, when the operating system will deallocate them.
Question: How to deallocate dynamically allocate memory without using “free()” function. void * realloc ( void *ptr, size_t size); If “size” is zero, then call to realloc is equivalent to “free(ptr)”. And if “ptr” is NULL and size is non-zero then call to realloc is equivalent to “malloc(size)”.
The documentation says this about the "s" format specifier to PyArg_ParseTuple
:
s
(string or Unicode) [const char *]
Convert a Python string or Unicode object to a C pointer to a character string. You must not provide storage for the string itself; a pointer to an existing string is stored into the character pointer variable whose address you pass.
That means that the pointer is pointing to memory that Python itself is managing.
If you dig into the Python source (I'm using version 3.2) you'll find PyArg_ParseTuple
in Python/getargs.c
. If you trace the execution (a mark-I eyeball should be sufficient if you already know C) you'll get to convertsimple
which handles some simple data type format strings (such as "s"). Then have a look at the 's'
branch of the switch and you'll see this:
char **p = va_arg(*p_va, char **);
/* ... */
*p = PyBytes_AS_STRING(uarg);
And a little grepping will yield the definition of PyBytes_AS_STRING
:
#define PyBytes_AS_STRING(op) (assert(PyBytes_Check(op)), \
(((PyBytesObject *)(op))->ob_sval))
So all this is really doing is handing you a pointer to a field, ob_sval
, inside the Python object; Python is managing the memory for its internal objects.
So, you shouldn't free your command
string because it ends up pointing into some of Python's internal data and Python itself is responsible for that memory. Hence the "hands off" warning in the documentation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With