나는 C에서 numpy 배열로 쓰는 파이썬 확장을 작성 해왔다. 테스트하는 동안, 필자는 일부 매우 큰 배열이 요소 중 일부에 액세스하려고 시도했을 때 segfault를 생성한다는 것을 알아 차렸다.^numpy-C API가 할당 실패에 대해 경고하지 않는 이유는 무엇입니까?
// Size of buffer we will write to
npy_intp buffer_len_alt = BUFFER_LENGTH;
//
PyArray_Descr * dtype;
dtype = PyArray_DescrFromType(NPY_BYTE);
PyObject* column = PyArray_Zeros(1, &buffer_len_alt, dtype, 0);
//Check that array creation succeeds
if (column == NULL){
// This exit point is not reached, so it looks like everything is OK
return (PyObject *) NULL;
}
// Get the array's internal buffer so we can write to it
output_buffer = PyArray_BYTES((PyArrayObject *)column);
// Try writing to the buffer
output_buffer[0] = 'x'; //No segfault
output_buffer[((int) buffer_len_alt) - 1] = 'x'; //Segfault here
I 체크하고 난 3기가바이트 대한 (즉 BUFFER_LENGTH 배열을 할당 할 때 오류에만 발생하였습니다 약 3 * 2 : 구체적으로는, 다음 코드 세그먼트의 마지막 라인 세그먼트 폴트 실패 30). 파이썬이 그것의 커스텀 할당자를 사용하고있다하더라도,이 크기의 할당이 실패하는 것은 not surprising입니다. 정말로 우려되는 것은 numpy가 오류를 발생시키지 않았거나 어레이 생성이 계획대로 진행되지 않았 음을 나타냅니다..
나는 이미 반환 된 배열에서 PyArray_ISCONTIGUOUS를 검사하고 PyArray_GETCONTIGUOUS를 사용하여 단일 메모리 세그먼트이지만 SEGFAULT가 여전히 발생하는지 확인하려고했습니다. NPY_ARRAY_DEFAULT는 연속 배열을 생성하므로 어쨌든 필요하지 않습니다.
확인해야 할 오류 플래그가 있습니까? 앞으로이 상황을 어떻게 감지/예방할 수 있습니까? BUFFER_LENGTH를 더 작은 값으로 설정하면 작동하지만이 값은 런타임에 결정되므로 정확한 경계를 알고 싶습니다.
EDIT : @DavidW 지적한 바와 npy_intp 64 비트 수가 될 수 있으므로
가 오류가 int로 buffer_len_alt 캐스팅에서 유래한다. 캐스트를 int로 변환하여 '부호없는 long'으로 변환하면 문제가 해결됩니다.
이것은 캐스팅 된 int ('((int) buffer_len_alt) - 1')와 관련이 있습니까? 아마도 서명 된 것일 뿐이므로'BUFFER_LENGTH'를 보유하지 못합니까? (32 비트 정수라고 가정) – DavidW
@DavidW 대답을해야합니다. 'buffer_len_alt'는'npy_intp' 타입입니다. 이것은 대부분의 플랫폼에서 64 비트 부호있는 정수입니다. 플랫폼상의'int' 형이 32 비트라면'buffer_len_alt'가'3 * (2 ** 30)'일 때'(int) buffer_len_alt'는 음의 정수가됩니다. –
@DavidW 조언을 주셔서 감사합니다! 나는 이것이 실제로 문제인지를 확인할 수있었습니다. 답변을 게시하면 승인 된 것으로 표시해야합니다. – Max