Cython structure, line from python to cython

I would like to convert a python object to a cython structure by doing as I did but does not assign simres [1] values ​​to resulta [x] .cpt1

cdef struct resultaStructure:
    double score
    char **cpt1

simRes = [1.0,
['http://bioontology.org/projects/ontologies/fma/fmaOwlDlComponent_2_0#Abdomen', 
'Abdomen']]
cdef x = 0 
cdef resultaStructure *resulta = <resultaStructure *> malloc(sizeof(resultaStructure)*labelsSourceTaille)

resulta[x].score = simRes[0]
print("score : ",resulta[0].score)

resulta[x].cpt1 = <char**> malloc (sizeof (char**)*2)
print('2')
resulta[x].cpt1[0] = <char*> malloc (sizeof (char)*simRes[1][0].__len__()+1)
print('3')
resulta[x].cpt1[1] = <char*> malloc (sizeof (char)*simRes[1][1].__len__()+1)
print('4')
resulta[x].cpt1[0] = <char*> simRes[1][0]
print('5')
resulta[x].cpt1[1] = <char*>  simRes[1][1]
print('6')

print("cpt1 0 : ",resulta[0].cpt1[0])
print("cpt1 1 : ",resulta[0].cpt1[1])

      

here is the result

('score:', 1.0)

2

3

4

+3


source to share


2 answers


The code in the question and in the OP's answer has serious issues that are likely to cause the program to crash in the long run.

1)

resulta[x].cpt1 = <char**> malloc (sizeof (char**)*2)

      

cpt1

is a pointer to (array of) char pointers. So it should be assigned as

resulta[x].cpt1 = <char*> malloc (sizeof (char*)*2)

      

(Better yet, if the length is always 2

, then assign char *cpt1[2]

in the struct definition and you don't need malloc

it.)

This is unlikely to cause a real problem as all pointers are the same size but still not the same.

2) (Real part of problem a)

resulta[x].cpt1[0] = <char*> malloc (sizeof (char)*simRes[1][0].__len__()+1)
# ...
resulta[x].cpt1[0] = <char*>some_python_string

      



This is where you allocate some memory, promptly forget about the allocated memory if you want to make a pointer in another memory area belonging to a Python string. What you are not doing is copying the data from the Python string to the allocated memory.

3) (Real part of problem b)

str1 = simRes[1][0].encode('UTF-8')
resulta[x].cpt1[0] = <char*> str1

      

The memory it points cpt1[0]

to belongs to str1

. If str1

freed before you finish using your structure, then the structure is pointing to invalid memory and your program will crash or read some random data that was allocated later, or some other bad thing.

If you can guarantee that it str1

will outlive your structure (for example, your structure is being used as an argument to a single C function call), then that's ok, but in general it probably isn't.

The solution is to copy the content or str1

to a new allocated memory:

resulta[x].cpt1[0] = <char*> malloc (sizeof (char)*len(simRes[1][0])+1)
strcpy(resulta[x].cpt1[0],str1)

      


(Also, you remember free

all the malloc

ed memory you have , right?)

+1


source


the solution is to encode the python string before assigning as shown below,



str1 = simRes[1][0].encode('UTF-8')
resulta[x].cpt1[0] = <char*> str1
print('5')
str2 = simRes[1][1].encode('UTF-8')
resulta[x].cpt1[1] = <char*> str2

      

+1


source







All Articles