【发布时间】:2011-10-17 18:06:13
【问题描述】:
我在 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 输入数组的值。)然后,如果我想为内存中的这些部分之一分配一个布尔值,我应该通过*(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);
}
【问题讨论】:
-
您正在使用
bool变量来存储指针/地址。NPY_BOOL(unsigned char) 和bool在您的平台上可能不一样。 -
我尝试将 true 或 false 进行类型转换:
(unsigned char) true也不太顺利。 -
我也尝试分配 1 或 0,这是我猜我之前是怎么做的。
*(state_out->data + i*state_out->strides[0]) = 1;也因 SegFault 而失败。 -
请贴出完整的Python测试代码,包括输入数据和预期输出。
-
@cgohlke 的上述评论意味着你应该写例如
npy_bool *adj_value = ...而不是bool adj_value = ...在处理指向布尔值的指针时。
标签: python c python-c-api