Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Python C API时的奇怪内存行为 我试图在C++库上使用Python C API实现Python包装器。我需要实现转换,以便在Python和C++中使用对象。我过去已经这样做了,但我有一个错误,我真的很难接受_Python_C++_Wrapper - Fatal编程技术网

使用Python C API时的奇怪内存行为 我试图在C++库上使用Python C API实现Python包装器。我需要实现转换,以便在Python和C++中使用对象。我过去已经这样做了,但我有一个错误,我真的很难接受

使用Python C API时的奇怪内存行为 我试图在C++库上使用Python C API实现Python包装器。我需要实现转换,以便在Python和C++中使用对象。我过去已经这样做了,但我有一个错误,我真的很难接受,python,c++,wrapper,Python,C++,Wrapper,我有一个非常基本的测试功能: PyObject* convert_to_python() { std::cout << "Convert to PyObject" << std::endl; long int a = 20; PyObject* py_a = PyInt_FromLong(a); std::cout << "Convert to PyObject ok" << std::endl; retur

我有一个非常基本的测试功能:

PyObject* convert_to_python() {
    std::cout << "Convert to PyObject" << std::endl;
    long int a = 20;
    PyObject* py_a = PyInt_FromLong(a);
    std::cout << "Convert to PyObject ok" << std::endl;
    return py_a;
}
我的输出是:

Convert to PyObject
Segmentation fault (core dumped)
我还对它运行了valgrind:

valgrind --tool=memcheck --track-origins=yes --leak-check=full ./my_convert
但它并没有给我太多关于它的信息:

Invalid read of size 8
==19030==    at 0x4F70A7B: PyInt_FromLong (in /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0)
==19030==    by 0x541E6BF: _object* pysmud_from<float>(smu::Matrix<float, 0, 0>&) (smu_type_conversions.cpp:308)
==19030==    by 0x43A144: (anonymous namespace)::Wrapper_ConvertMatrix_Test::Body() (test_wrapper.cpp:12)
==19030==    by 0x43A0C6: (anonymous namespace)::Wrapper_ConvertMatrix_Test::TestBody() (test_wrapper.cpp:10)
==19030==    by 0x465B4D: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2078)
==19030==    by 0x460684: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2114)
==19030==    by 0x444C05: testing::Test::Run() (gtest.cc:2151)
==19030==    by 0x4454C9: testing::TestInfo::Run() (gtest.cc:2326)
==19030==    by 0x445BEA: testing::TestCase::Run() (gtest.cc:2444)
==19030==    by 0x44CF41: testing::internal::UnitTestImpl::RunAllTests() (gtest.cc:4315)
==19030==    by 0x46712C: bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) (gtest.cc:2078)
==19030==    by 0x461532: bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) (gtest.cc:2114)
==19030==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
大小为8的读取无效
==19030==at 0x4F70A7B:PyInt_FromLong(in/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0)
==19030==0x541E6BF:_object*pysmud_from(smu::Matrix&)(smu类型转换。cpp:308)
==19030==by 0x43A144:(匿名命名空间)::Wrapper\u ConvertMatrix\u Test::Body()(Test\u Wrapper.cpp:12)
==19030==by 0x43A0C6:(匿名命名空间)::Wrapper\u ConvertMatrix\u Test::TestBody()(Test\u Wrapper.cpp:10)
==19030==by 0x465B4D:void testing::internal::HandleSehExceptionsInMethodIfSupported(testing::Test*,void(testing::Test::*)(),char const*)(gtest.cc:2078)
==19030==by 0x460684:void testing::internal::HandleExceptionsInMethodIfSupported(testing::Test*、void(testing::Test::*)()、char const*)(gtest.cc:2114)
==19030==by 0x444C05:testing::Test::Run()(gtest.cc:2151)
==19030==by 0x4454C9:testing::TestInfo::Run()(gtest.cc:2326)
==19030==by 0x445BEA:testing::TestCase::Run()(gtest.cc:2444)
==19030==by 0x44CF41:testing::internal::UnitTestImpl::RunAllTests()(gtest.cc:4315)
==19030==by 0x46712C:bool testing::internal::handlesehExceptionsinMethodiSupported(testing::internal::UnitTestImpl*,bool(testing::internal::UnitTestImpl::*)(),char const*)(gtest.cc:2078)
==19030==by 0x461532:bool测试::内部::HandleExceptionsInMethodiSupported(测试::内部::UnitTestImpl*,bool(测试::内部::UnitTestImpl::*)(),char const*)(gtest.cc:2114)
==19030==地址0x0不是堆栈、malloc或(最近)空闲
我认为这段代码应该可以工作,但我不知道我写的有什么错。我是否错误地包含或链接了Python文件和库

编辑:不提供任何错误

#include <Python.h>

PyObject* convert_long_int(long int a) {
  PyObject *ret = PyInt_FromLong(a);
  return ret;
}

int main(void) {
  long int a = 65454984;
  PyObject *pya = convert_long_int(a);
  return 0;
}
#包括
PyObject*转换长整型(长整型a){
PyObject*ret=PyInt_FromLong(a);
返回ret;
}
内部主(空){
长整数a=65454984;
PyObject*pya=转换长整型(a);
返回0;
}
如果使用
gcc-o wraptest-I/usr/include/python2.7 wraptest.c-L/usr/lib/x86_64-linux-gnu/-lpython2.7进行编译


初始化是做什么的

如果省略初始化,我可以确认Ubuntu 16.04和Python 2.7上的分段错误

看看这个例子

#include <Python.h>

int
main(int argc, char *argv[])
{
  Py_SetProgramName(argv[0]);  /* optional but recommended */
  Py_Initialize();
  PyRun_SimpleString("from time import time,ctime\n"
                     "print 'Today is',ctime(time())\n");
  Py_Finalize();
  return 0;
}
它可以正常工作


这两个例子之间的区别是

long int a = 20;

我想,这和

当前的实现为-5到256之间的所有整数保留一个整数对象数组,当您在该范围内创建一个int时,实际上只返回对现有对象的引用

可能Python试图在没有初始化的情况下访问未初始化的指针或内存范围

当我使用
a=256
更改示例时,它崩溃了。使用
a=257
,它不会


查看,您可以看到一个指针数组

static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
可在中的正下方访问

但是没有从中初始化

for(ival=-NSMALLPOSINTS;ivalob_ival=ival;
小整数[ival+NSMALLNEGINTS]=v;
}

这些指针都是
NULL
,导致崩溃。

您知道返回后的cout语句永远不会显示,对吗?这是打字错误吗:p?这是我的错误,报税表是以前的。我在写问题时把它放错了位置。我尝试了一个简单的main,用
gcc-o wraptest-I/usr/include/python2.7 wraptest.c-L/usr/lib/x86_64-linux-gnu/-lpython2.7
编译时也没有出现错误。但在这种情况下,我也没有初始化。
long int a = 20;
long int a = 65454984;
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
v = small_ints[ival + NSMALLNEGINTS];
Py_INCREF(v);
for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++) {
    if (!free_list && (free_list = fill_free_list()) == NULL)
        return 0;
    /* PyObject_New is inlined */
    v = free_list;
    free_list = (PyIntObject *)Py_TYPE(v);
    (void)PyObject_INIT(v, &PyInt_Type);
    v->ob_ival = ival;
    small_ints[ival + NSMALLNEGINTS] = v;
}