Reputation: 123
I ran such code in C++11:
PyObject* aa = PyLong_FromLong(7L);
Then I checked the value of aa
, it's not NULL
, but aa->ob_type
was NULL
.
However, when I ran:
PyObject* aa = PyLong_FromLong(257L);
aa->ob_type
was not NULL
anymore. I read the document of PyLong_FromLong, and found this:
PyObject* PyLong_FromLong(long v)
Return value: New reference.
Return a new PyLongObject object from v, or NULL on failure.
The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object. So it should be possible to change the value of 1. I suspect the behaviour of Python in this case is undefined. :-)
Seems that when building PyLongObject
between -5 and 256 will meet this problem. But I don't understand the reason.
What's more, this problem doesn't appear in Python2. That's incredible!
Upvotes: 0
Views: 1079
Reputation: 30888
You haven't initialized Python. Since these small objects are special-cased they are set up when Python is initialized.
#include <Python.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
Py_Initialize();
PyObject* aa = PyLong_FromLong(7L);
printf("aa=%d\naa->ob_type=%p\n",PyLong_AsLong(aa),aa->ob_type);
Py_Finalize();
return 0;
}
correctly prints
aa=7
aa->ob_type=0x7f380d6b5800
(note that this will vary from run to run)
If I comment out Py_Initialize()
and Py_Finalize()
then I get a segmentation fault, but if I don't try reading the value with PyLong_AsLong
then I get a null pointer for ob_type
.
The documentation does tell you to initialize the interpreter.
With respect to Python2 it has two integer types PyInt
and PyLong
with PyInt
handling the small values and so having the special-cased table. You'll probably see the same issue if you use PyInt
in Python2. Anything you do with Python before calling Py_Initialize
is undefined though, so it could fail in different exciting ways.
Upvotes: 1