1

I have a problem that when using in a ctypes (python) structure c_char_p, after having saved the structure in the file and finished the code. When the structure is read with readinto and the attribute signed with c_char_p is called, segmentation fault appears.

Code:

import ctypes


class A(ctypes.Structure):
    _pack_ = 1
    _fields_ = [("x", ctypes.c_char_p)]


test_char = b"Hello world"


# line 13-18
with open("test.struct", "wb+") as f:
    root = A(test_char)
    f.write(root)
    print(root.x)
    del root
    f.close() # ignore

# test 1
with open("test.struct", "rb+") as f:
    lii = A()
    f.readinto(lii)
    # Segmentation Fault when trying to convert bytes to c_char_p
    print(lii.x)
    f.close()
    del lii

# test 2
with open("test.struct", "rb+") as f:
    lii = A()
    f.readinto(lii)
    print(lii.x)
    f.close()
    del lii

So far everything works fine, But let's delete from line 13 to 18 of this file: The result is segmentation fault in print(lii.x).

In some cases when the signature is changed to c_wchar_p it gives an invalid range of unicode characters, making it known that there is a bit mess when SAVING the structure in the file.

When using c_char or c_wchar it works perfect.

Is there a solution or did I something wrong?

  • Have no problem executing your code with python 2 & 3. – Ptit Xav Dec 06 '21 at 22:24
  • Did you remove the lines? (I am on python 3.10) –  Dec 06 '21 at 22:28
  • I can reproduce the problem, but what are you trying to do here? Do you want to save the string value to the file? It will just save the pointer address - there might not be anything at that address when it is later read in. Observe the fact that the file `test.struct` is 8 bytes long, regardless of the length of `test_char`. – alani Dec 06 '21 at 22:28
  • Exactly, I want to save the char string found in the structure in the file. –  Dec 06 '21 at 22:30
  • 1
    So you will need to use an array rather than a pointer. So your structure would have to contain an array as long as the longest string that you might want it to contain, if you are going to do it this way. But what is the ultimate aim here? Are you specifically wanting to use ctypes? Or could you, for example, write to a pickle file? – alani Dec 06 '21 at 22:35
  • save structures in the file and then reuse it, then make a persistent btree. –  Dec 06 '21 at 22:40
  • Well the problem with C structures is that they are fixed length. You could change your `ctypes.c_char_p` to `ctypes.c_char * max_length` for some suitably chosen maximum length (to use an array), but it is potentially wasteful. But there isn't much point in storing the memory address, which is what the original code does. Regarding my suggested alternative approach, for example if you have a dictionary containing simple Python data types, you can pickle that - https://stackoverflow.com/questions/11218477/how-can-i-use-pickle-to-save-a-dict – alani Dec 06 '21 at 22:55
  • Thanks, I have one more question: I am using C structures because I think it can read and write according to the buffer offset (Which means it can be fast), is this true? –  Dec 06 '21 at 23:07
  • If you were asking me, I don't know. Maybe someone else can help. – alani Dec 06 '21 at 23:12

0 Answers0