1

I'm trying to build a simple C extension for Python, initially I'm trying to return the contents of an unsigned char array (binary data).

unsigned char frame_out[200];
// test data
for (int i = 0; i < 199; i++) {
    frame_out[i] = (i&0xff);
}
PyObject* result = Py_BuildValue("y#", frame_out, 199);
return result;

The code above works fine and I can print the test values in Python. But I want the array, frame_out, to be dynamic so I use new() as shown below.

char* frame_out = new char[200]
// test data
for (int i = 0; i < 199; i++) {
    frame_out[i] = (i&0xff);
}
PyObject* result = Py_BuildValue("y#", frame_out, 199);
return result;

This now gives an error when called from Python:

Process finished with exit code -1073741819 (0xC0000005)

I have also tried using malloc:

char* frame_out = (char* )malloc( sizeof(char) * 200);

But this gives the same error.

I have checked result and this is not null. What have I done wrong?

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Garry
  • 11
  • 2
  • Seems right to me. Are you sure the error isn’t somewhere else? (The nature of C is that memory problems can produce crashes in seemingly unrelated places.) Building a debug version of Python isn’t convenient, but you might have to do it. – Ry- Aug 15 '20 at 10:57
  • Ah, the note at https://docs.python.org/3/c-api/arg.html#strings-and-buffers says you might want to check whether `PY_SSIZE_T_CLEAN` is defined. (And even if not, define it and pass `(Py_ssize_t)199` anyway.) – Ry- Aug 15 '20 at 10:59
  • You have a memory leak in any case. Python will make a copy of the memory rather than take ownership of it and you never delete the array – DavidW Aug 15 '20 at 17:12
  • Thanks guys, the code I have shown is a cut down version. I have defined PY_SSIZE_T_CLEAN. I'm sure the problem is in this part as it works if I use a simple array. I'm not concerned about the memory leak as this is handle in another part that I have not shown – Garry Aug 16 '20 at 11:35
  • If you’ve defined `PY_SSIZE_T_CLEAN`, you definitely have to pass `(Py_ssize_t)199`. Just `199` on its own is incorrect. That might not fix your current problem, but it is a fix for a problem. – Ry- Aug 16 '20 at 11:40

0 Answers0