`我的指针为空?

2024-10-01 04:53:44 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写包含bllipparserPython模块的代码。给它提供相同的数据集,它会间歇性崩溃(可能三到十次运行一次)。通过lldb,我发现RerankerModelsource)的公共字段{},显然只设置了一次(在构造函数中),随机变成{}(在我的运行期间,我只有一个RerankerModel,因此应该有一个weights,始终保持不变)。所以我设置了一个埋伏(我的意思是,一个观察点:我停止了构造函数和watchpoint set expression -w write -- &weights)中的代码,显然使指针无效的罪魁祸首是tiny_malloc_from_free_list来自libsystem_malloc.dylib。以下是相关的回溯顶部:

* thread #1, queue = 'com.apple.main-thread', stop reason = watchpoint 4
  * frame #0: 0x00007fff61caf22a libsystem_malloc.dylib`tiny_malloc_from_free_list + 151
    frame #1: 0x00007fff61cae3bf libsystem_malloc.dylib`szone_malloc_should_clear + 422
    frame #2: 0x00007fff61cae1bd libsystem_malloc.dylib`malloc_zone_malloc + 103
    frame #3: 0x00007fff61cad4c7 libsystem_malloc.dylib`malloc + 24
    frame #4: 0x00007fff5faac628 libc++abi.dylib`operator new(unsigned long) + 40
    frame #5: 0x00000001133c904c _CharniakParser.cpython-36m-darwin.so`std::__1::__split_buffer<short, std::__1::allocator<short>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<short>&) [inlined] std::__1::__allocate(__size=4) at new:226
    frame #6: 0x00000001133c9040 _CharniakParser.cpython-36m-darwin.so`std::__1::__split_buffer<short, std::__1::allocator<short>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<short>&) [inlined] std::__1::allocator<short>::allocate(this=0x0000000135316448, __n=2, (null)=0x0000000000000000) at memory:1747
    frame #7: 0x00000001133c8f44 _CharniakParser.cpython-36m-darwin.so`std::__1::__split_buffer<short, std::__1::allocator<short>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<short>&) [inlined] std::__1::allocator_traits<std::__1::allocator<short> >::allocate(__a=0x0000000135316448, __n=2) at memory:1502
    frame #8: 0x00000001133c8f16 _CharniakParser.cpython-36m-darwin.so`std::__1::__split_buffer<short, std::__1::allocator<short>&>::__split_buffer(this=0x00007ffeefbf3b48, __cap=2, __start=1, __a=0x0000000135316448) at __split_buffer:311
    frame #9: 0x00000001133c878d _CharniakParser.cpython-36m-darwin.so`std::__1::__split_buffer<short, std::__1::allocator<short>&>::__split_buffer(this=0x00007ffeefbf3b48, __cap=2, __start=1, __a=0x0000000135316448) at __split_buffer:310
    frame #10: 0x00000001133c869b _CharniakParser.cpython-36m-darwin.so`void std::__1::vector<short, std::__1::allocator<short> >::__push_back_slow_path<short const>(this=0x0000000135316438 size=1, __x=0x00007ffeefbf3caa) at vector:1567
    frame #11: 0x00000001133c4446 _CharniakParser.cpython-36m-darwin.so`Val::extendTrees(Bst&, int) [inlined] std::__1::vector<short, std::__1::allocator<short> >::push_back(this=0x0000000135316438 size=1, __x=0x00007ffeefbf3caa) at vector:1588
我不是一个C++专家,但是…分配器如何使指针为空?分配器怎么知道指针在哪里?为什么分配器将指针置空?我的意思是,我可以看到我可能会用尽内存,我所做的并不是完全内存不足,但我更希望分配器分配失败,而不是随机释放某个东西——我不知道它会使指针为空。有人能给我解释一下它是如何工作的吗,为什么会发生,它是如何发生的,为什么在一个有很多其他有趣的指针的代码中总是同一个指针,以及我能做些什么使它不发生?在

如果需要的话,附录:这里是实际的空值发生的地方,tiny_malloc_from_free_list的代码,如果有人能理解的话。。。在

^{pr2}$

违规者是0x7fff61caf227 <+148>: movq %rdx, (%rax),其中rax是我的weights指针的地址,该指针为空,rdx为0。在


Tags: sobuffercpythonframeatlongallocatorsplit
1条回答
网友
1楼 · 发布于 2024-10-01 04:53:44

应该是:

  1. 数据集中存在转义序列\0。使用python计算字符串的大小:

    >>> len("a\0aa")
    4
    
  2. 然后,字符串被传递给c++(CharniakParser),我们循环它来解析它:

    string a = "a\0aa";
    const char* b = a.c_str();
    cout << a.size() << endl; // size == 1, \0 is the end of a string
    for(size_t i=0; i<4; i++)// 4 is the string size calculated with python
    {
        const char* c = &b[i];
        do_something_with(c); // c is corrupt after i == 0
    }
    
  3. 由于内存即将用完,损坏的指针c将指向一个非空地址(假设并非总是同一个指针无效),所指向的对象被操作删除,因此在代码的另一部分,您有一个指针指向已删除的对象>;这是您的错误

我知道我的解释有些牵强,但我们没有那么多数据。在

相关问题 更多 >