gpt4 book ai didi

python - 尝试写入 C 扩展中创建的 Numpy 数组时出现 SegFault

转载 作者:行者123 更新时间:2023-11-30 18:04:07 25 4
gpt4 key购买 nike

我在 for 循环中有一个 if 子句,其中我预先定义了 state_out:

state_out = (PyArrayObject *) PyArray_FromDims(1,dims_new,NPY_BOOL);

if 条件是这样的:

        if (conn_ctr<sum*2){
*(state_out->data + i*state_out->strides[0]) = true;
}
else {
*(state_out->data + i*state_out->strides[0]) = false;
}

当注释掉这些时,state_out 以全假 Numpy 数组的形式返回。这个作业有一个我看不到的问题。据我所知,这段代码中调用的 struct PyArrayObject 中的所有内容都是指针,因此在指针运算之后,它应该指向我打算写入的地址。 (代码中的所有 if 条件都是通过以这种方式获取值来构建的,并且我知道它是有效的,因为我设法 printf 输入数组的值。)然后,如果我想将 bool 分配给内存中的这些部分之一,我应该通过 *(pointer_intended) = true 分配它,我缺少什么?

编辑:我发现即使我没有达到这些值,即使我在其中放置了一些 printf 函数:

if (conn_ctr<sum*2){
printf("True!\n");
}
else {
printf("False!\n");
}

我再次遇到 SegFault。

非常感谢,其余的代码在这里。

#include <Python.h>
#include "numpy/arrayobject.h"
#include <stdio.h>
#include <stdbool.h>

static PyObject* trace(PyObject *self, PyObject *args);

static char doc[] =
"This is the C extension for xor_masking routine. It interfaces with Python via C-Api, and calculates the"
"next state with C pointer arithmetic";

static PyMethodDef TraceMethods[] = {
{"trace", trace, METH_VARARGS, doc},
{NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
inittrace(void)
{
(void) Py_InitModule("trace", TraceMethods);
import_array();
}

static PyObject* trace(PyObject *self, PyObject *args){
PyObject *adjacency ,*mask, *state;
PyArrayObject *adjacency_arr, *mask_arr, *state_arr, *state_out;

if (!PyArg_ParseTuple(args,"OOO:trace", &adjacency, &mask, &state)) return NULL;

adjacency_arr = (PyArrayObject *)
PyArray_ContiguousFromObject(adjacency, NPY_BOOL,2,2);

if (adjacency_arr == NULL) return NULL;
mask_arr = (PyArrayObject *)
PyArray_ContiguousFromObject(mask, NPY_BOOL,2,2);

if (mask_arr == NULL) return NULL;
state_arr = (PyArrayObject *)
PyArray_ContiguousFromObject(state, NPY_BOOL,1,1);

if (state_arr == NULL) return NULL;

int dims[2], dims_new[1];
dims[0] = adjacency_arr -> dimensions[0];
dims[1] = adjacency_arr -> dimensions[1];
dims_new[0] = adjacency_arr -> dimensions[0];
if (!(dims[0]==dims[1] && mask_arr -> dimensions[0] == dims[0]
&& mask_arr -> dimensions[1] == dims[0]
&& state_arr -> dimensions[0] == dims[0]))
return NULL;


state_out = (PyArrayObject *) PyArray_FromDims(1,dims_new,NPY_BOOL);

int i,j;

for(i=0;i<dims[0];i++){
int sum = 0;
int conn_ctr = 0;

for(j=0;j<dims[1];j++){

bool adj_value = (adjacency_arr->data + i*adjacency_arr->strides[0]
+j*adjacency_arr->strides[1]);

if (*(bool *) adj_value == true){

bool mask_value = (mask_arr->data + i*mask_arr->strides[0]
+j*mask_arr->strides[1]);
bool state_value = (state_arr->data + j*state_arr->strides[0]);

if ( (*(bool *) mask_value ^ *(bool *)state_value) == true){
sum++;
}
conn_ctr++;
}
}

if (conn_ctr<sum*2){

}
else {

}
}

Py_DECREF(adjacency_arr);
Py_DECREF(mask_arr);
Py_DECREF(state_arr);
return PyArray_Return(state_out);
}

最佳答案

    if (conn_ctr<sum*2){
*(state_out->data + i*state_out->strides[0]) = true;
}
else {
*(state_out->data + i*state_out->strides[0]) = false;
}

这里我天真地做了一个指针运算,state_out->data是一个指向data开头的指针,它被定义为char的指针:SciPy Doc - Python Types and C-Structures

typedef struct PyArrayObject {
PyObject_HEAD
char *data;
int nd;
npy_intp *dimensions;
npy_intp *strides;
...
} PyArrayObject;

我在这里复制了其中的一部分。 state_out->strides 是一个指向数组的指针,该数组的长度为我们拥有的数组的维度。在本例中这是一个一维数组。因此,当我进行指针算术 (state_out->data + i*state_out->strides[0]) 时,我的目标当然是计算指向数组第 i 个值的指针,但我失败了给出指针的类型,因此

我尝试过:

NPY_BOOL *adj_value_ptr, *mask_value_ptr, *state_value_ptr, *state_out_ptr;

其中的变量指向我对 for 循环感兴趣的值,而 state_out_ptr 是我正在写入的值。我原以为自从我声明这些数组的组成部分的类型为NPY_BOOL,指向数组内数据的指针也将是NPY_BOOL类型。 当使用直接操作内存的数据时,此操作会失败并出现 SegFault。这是因为 NPY_BOOL 是一个整数的 enum (如注释中善意的 pv 所示)。供 NumPy 在内部使用。有一个 C typedef npy_bool 以便在代码中使用 bool 值。 Scipy Docs 。当我引入类型为

的指针时
npy_bool *adj_value_ptr, *mask_value_ptr, *state_value_ptr, *state_out_ptr;

段错误消失了,我成功地操作并返回了一个 Numpy 数组。

我不是专家,但这解决了我的问题,如果我错了,请指出。

源代码中发生变化的部分是:

state_out = (PyArrayObject *) PyArray_FromDims(1,dims_new,NPY_BOOL);

npy_bool *adj_value_ptr, *mask_value_ptr, *state_value_ptr, *state_out_ptr;
npy_intp i,j;

for(i=0;i<dims[0];i++){
npy_int sum = 0;
npy_int conn_ctr = 0;

for(j=0;j<dims[1];j++){

adj_value_ptr = (adjacency_arr->data + i*adjacency_arr->strides[0]
+j*adjacency_arr->strides[1]);

if (*adj_value_ptr == true){

mask_value_ptr = (mask_arr->data + i*mask_arr->strides[0]
+j*mask_arr->strides[1]);

state_value_ptr = (state_arr->data + j*state_arr->strides[0]);

if ( (*(bool *) mask_value_ptr ^ *(bool *)state_value_ptr) == true){
sum++;
}
conn_ctr++;
}
}
state_out_ptr = (state_out->data + i*state_out->strides[0]);
if (conn_ctr < sum*2){
*state_out_ptr = true;
}
else {
*state_out_ptr = false;
}
}

关于python - 尝试写入 C 扩展中创建的 Numpy 数组时出现 SegFault,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7774524/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com