Accessing Object Memory Address
The Python manual has this to say about id()
:
Return the "identity'' of an object.
This is an integer (or long integer)
which is guaranteed to be unique and
constant for this object during its
lifetime. Two objects with
non-overlapping lifetimes may have the
same id() value. (Implementation note:
this is the address of the object.)
So in CPython, this will be the address of the object. No such guarantee for any other Python interpreter, though.
Note that if you're writing a C extension, you have full access to the internals of the Python interpreter, including access to the addresses of objects directly.
How to get the memory address of an object with `this` reference inside the class in C++
void Obj::method()
{
cout << &*this << " or " << this << endl;
}
Accessing specific memory locations in C
Common C compilers will allow you to set a pointer from an integer and to access memory with that, and they will give you the expected results. However, this is an extension beyond the C standard, so you should check your compiler documentation to ensure it supports it. This feature is not uncommonly used in kernel code that must access memory at specific addresses. It is generally not useful in user programs.
As comments have mentioned, one problem you may be having is that your operating system loads programs into a randomized location each time a program is loaded. Therefore, the address you discover on one run will not be the address used in another run. Also, changing the source and recompiling may yield different addresses.
To demonstrate that you can use a pointer to access an address specified numerically, you can retrieve the address and use it within a single program execution:
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
int main(void)
{
// Create an int.
int x = 0;
// Find its address.
char buf[100];
sprintf(buf, "%" PRIuPTR, (uintptr_t) &x);
printf("The address of x is %s.\n", buf);
// Read the address.
uintptr_t u;
sscanf(buf, "%" SCNuPTR, &u);
// Convert the integer value to an address.
int *p = (int *) u;
// Modify the int through the new pointer.
*p = 123;
// Display the int.
printf("x = %d\n", x);
return 0;
}
Obviously, this is not useful in a normal program; it is just a demonstration. You would use this sort of behavior only when you have a special need to access certain addresses.
Can I get a Python object from its memory address?
You're almost certainly asking the wrong question, and Raymond Hettinger's answer is almost certainly what you really want.
Something like this might be useful trying to dig into the internals of the CPython interpreter for learning purposes or auditing it for security holes or something… But even then, you're probably better off embedding the Python interpreter into a program and writing functions that expose whatever you want into the Python interpreter, or at least writing a C extension module that lets you manipulate CPython objects.
But, on the off chance that you really do need to do this…
First, there is no reliable way to even get the address from the repr
. Most objects with a useful eval
-able representation will give you that instead. For example, the repr of ('1', 1)
is "('1', 1)"
, not <tuple at 0x10ed51908>
. Also, even for objects that have no useful representation, returning <TYPE at ADDR>
is just an unstated convention that many types follow (and a default for user-defined classes), not something you can rely on.
However, since you presumably only care about CPython, you can rely on id
:
CPython implementation detail: This is the address of the object in memory.
(Of course if you have the object to call id
(or repr
) on, you don't need to dereference it via pointer, and if you don't have the object, it's probably been garbage collected so there's nothing to dereference, but maybe you still have it and just can't remember where you put it…)
Next, what do you do with this address? Well, Python doesn't expose any functions to do the opposite of id
. But the Python C API is well documented—and, if your Python is built around a shared library, that C API can be accessed via ctypes
, just by loading it up. In fact, ctypes
provides a special variable that automatically loads the right shared library to call the C API on, ctypes.pythonapi
.
In very old versions of ctypes
, you may have to find and load it explicitly, like pydll = ctypes.cdll.LoadLibrary('/usr/lib/libpython2.5.so')
(This is for linux with Python 2.5 installed into /usr/lib; obviously if any of those details differ, the exact command line will differ.)
Of course it's much easier to crash the Python interpreter doing this than to do anything useful, but it's not impossible to do anything useful, and you may have fun experimenting with it.
Is it possible to access an object via memory address?
I have created a shared library that contains the following code:
#include "Python.h"
extern "C" __declspec(dllexport) PyObject* PyObjectFromAdress(long addr) {
return (PyObject*) addr;
}
compiled it and wrapped it using ctypes:
import ctypes
dll = ctyes.cdll.thedll
object_from_id = dll.PyObjectFromAdress
object_from_id.restype = ctypes.py_object()
Now you can exchange python objects through their memory adress within one python process.
l1 = []
l2 = object_from_id( id(l1) )
print l1 == l2
l1.append(9)
print l2
But be aware of already garbage collected objects ! The following code will crash the Python interpreter.
l2 = object_from_id( id([]) )
l2.append(8)
how to get memory location of a variable in Python
You can’t, but the reason is so fundamental that I think it worth posting anyway. In C, a pointer can be formed to any variable, including another pointer. (Another pointer variable, that is: you can write &p
, but not &(p+1)
.) In Python, every variable is a pointer but every pointer is to an object.
A variable, not being an object, cannot be the referent of a pointer. Variables can however be parts of objects, accessed either as o.foo
or o[bar]
(where bar might be an index or a dictionary key). In fact, every variable is such an object component except a local variable; as a corollary, it is impossible to assign to a local variable from any other (non-nested) function. By contrast, C does that regularly by passing &local
to whatever other function.
This distinction is readily illustrated by C++ containers: they typically provide operator[]
to return a reference (a pointer that, like a Python reference, is automatically dereferenced) to an element to which =
can be applied, whereas the Python equivalent is to provide both __getitem__
(to return a reference) and __setitem__
(which implements []=
all at once to store to a variable).
In CPython’s implementation, of course, each Python variable is a PyObject*
variable, and a PyObject**
to one can be used for internal purposes, but those are always temporary and do not even conceptually exist at the Python level. As such, there is no equivalent for id
for them.
Related Topics
Get Name of Current Script in Python
Conditionally Fill Column Values Based on Another Columns Value in Pandas
How to Decorate an Instance Method with a Decorator Class
Numpy.Unique with Order Preserved
How to Upgrade to Python 3.6 with Conda
How to Trigger Function on Value Change
How to Generate Circular Thumbnails with Pil
Class That Acts as Mapping for **Unpacking
Sum of List of Lists; Returns Sum List
Progress Indicator During Pandas Operations
How to Create Full Compressed Tar File Using Python
How to Handle a Broken Pipe (Sigpipe) in Python
Removing Unicode \U2026 Like Characters in a String in Python2.7
How to Find Where Python Is Installed on Windows
Calculating Arithmetic Mean (One Type of Average) in Python
Why Does Python Pep-8 Strongly Recommend Spaces Over Tabs for Indentation