Ctypes in python size using `sys.getsizeof (Var)` versus `ctypes.sizeof (Var)`
I have a question about the size of a variable in python, I am using Ctypes because I want 1 byte, but when I tried to check its size in python (through sys.getsize
) it said it was 80 bytes but when I checked ctypes (through ctypes.sizeof
) it said it was only 1 byte, can someone tell me what is the difference and why there are 2 different sizes? is it because python is using an object or a wrapper? and when it is sent to c does it view the real size?
import sys
import ctypes
print("size in ctypes is : ",ctypes.sizeof(ctypes.c_byte(1)))
print("size in sys is : ",sys.getsizeof(ctypes.c_byte(1)))
leads to
size in ctypes is : 1
size in sys is : 80
source to share
If you want to know the details, you should look objects.h
(especially the comments at the top of the file), yours ctypes.c_byte(1)
is a Python object:
>>> import sys
>>> import ctypes
>>> isinstance(ctypes.c_byte(1), object)
True
As @Daniel pointed out, sys.getsizeof
gets the size of this Python object. This Python object is larger than the corresponding object in C. Note the following comments object.h
:
Objects are structures allocated on the heap. . . .
The actual memory allocated for an object
contains other data that can only be accessed after casting the pointer
to a pointer to a longer structure type. This longer type must start
with the reference count and type fields; the macro PyObject_HEAD should be
used for this.
In other words, the macro is PyObject_HEAD
attached to the beginning of each object. This increases the size of the Python object.
ctypes.sizeof
, on the other hand, returns the actual size of the data type C
that is inside the Python object (using the C operator sizeof
).
EDIT
In light of your purpose, which you mentioned in your comment on Daniel's post, it is possible to send one byte through a server in Python 3.x. Below is an example of how you should send a byte using a Python module socket
to prove this point.
Here is the server that you will run in a single Python interpreter:
# Server
import socket
HOST = '' # All available interfaces
PORT = 50007 # Same port as client
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print('Connected by', addr)
while True:
data = conn.recv(1) # receive data with bufsize 1; a larger bufsize will break this code
if not data: break
conn.sendall(data)
conn.close()
Here is a client that you will run in another python interpreter:
# Client
import socket
HOST = '127.0.0.1' # The remote host, but here using localhost
PORT = 50007 # The port used by both the client and server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'1') # a bytes object
data = s.recv(1) # Receive data from the socket with bufsize of 1
s.close()
print('Received', repr(data)) # confirm receipt
source to share
The ctypes module is used to create and manipulate C data types in Python. This is why ctypes.sizeof (ctypes.c_byte (1)) returns 1.
>>> import sys
>>> help(sys.getsizeof) Help on built-in function getsizeof in module sys:
getsizeof(...)
getsizeof(object, default) -> int
Return the size of object in bytes.
and
>>> import ctypes
>>> help(ctypes.sizeof)
Help on built-in function sizeof in module _ctypes:
sizeof(...)
sizeof(C type) -> integer
sizeof(C instance) -> integer
Return the size in bytes of a C instance
>>>
source to share