在c++中调用new_allocator后,参数值丢失

parameter value lost after call new_allocator in c++

本文关键字:参数 allocator c++ 调用 new      更新时间:2023-10-16

我在一个c++11程序中遇到了一个奇怪的行为,不知道出了什么问题。请给我一些建议。谢谢

基本上,它是一个OpenCL程序

struct memory_layout
{
public:
    memory_layout(managed_device d);
    scalar<int> s;
};
memory_layout::memory_layout(managed_device d) :
    s(d)
{
}
class doer
{
public:
    doer();
    void go();
private:
    managed_device dev;
    memory_layout mem;
};
doer::doer():
    dev(find_CPU()),
    mem(dev)
{
}
void doer::go()
{
    task t = copy(10,mem.s);               
}
int main(){
    doer d;
    d.go();
    return 0;
}

当它运行到复制功能时,它有"分段故障"。

以下是副本的定义:

template <typename T>
task copy(const T& source, scalar<T>& sink, const std::vector<task>& deps = {} )
{
    return sink.device().create_task( profile::copy<T>(source, sink), deps ); 
}

当我使用gdb进行调试时:

Breakpoint 1, doer::go (this=0x7fffffffdc90) at main.cpp:79
79          task t = copy(10,mem.s);               // device() original be 0x60f0d0
(gdb) p mem.s.device()
$1 = (cppcl::opencl_1_2::device::managed_device &) @0x7fffffffdc60: {_device = 0x60f0d0}
(gdb) s
std::vector<unsigned long, std::allocator<unsigned long> >::vector (this=0x7fffffffdc50) at /usr/include/c++/4.8.3/bits/stl_vector.h:249
249           : _Base() { }
(gdb) 
std::_Vector_base<unsigned long, std::allocator<unsigned long> >::_Vector_base (this=0x7fffffffdc50)
    at /usr/include/c++/4.8.3/bits/stl_vector.h:125
125           : _M_impl() { }
(gdb) 
std::_Vector_base<unsigned long, std::allocator<unsigned long> >::_Vector_impl::_Vector_impl (this=0x7fffffffdc50)
    at /usr/include/c++/4.8.3/bits/stl_vector.h:87
87              : _Tp_alloc_type(), _M_start(0), _M_finish(0), _M_end_of_storage(0)
(gdb) 
std::allocator<unsigned long>::allocator (this=0x7fffffffdc50) at /usr/include/c++/4.8.3/bits/allocator.h:113
113           allocator() throw() { }
(gdb) 
__gnu_cxx::new_allocator<unsigned long>::new_allocator (this=0x7fffffffdc50) at /usr/include/c++/4.8.3/ext/new_allocator.h:80
warning: Source file is more recent than executable.
80
(gdb) 
std::_Vector_base<unsigned long, std::allocator<unsigned long> >::_Vector_impl::_Vector_impl (this=0x7fffffffdc50)
    at /usr/include/c++/4.8.3/bits/stl_vector.h:88
88              { }
(gdb) 
cppcl::opencl_1_2::device::copy<int> (source=@0x7fffffffdc6c: 10, sink=..., deps=std::vector of length 0, capacity 0)
    at /usr/include/cppcl/1.2/device/buffer_templates.h:1233
warning: Source file is more recent than executable.
1233        return sink.device().create_task( profile::copy<T>(source, sink), deps ); 
(gdb) p sink.device()
$2 = (cppcl::opencl_1_2::device::managed_device &) @0x7fffffffdc60: {_device = 0x0}

在我进入复制函数后,它首先构建了"deps"参数,然后,_device值变为0x0。我不明白为什么这么开心?

谢谢你给我一些建议。

我假设你不是在问你的代码出了什么问题,你只是在问如何自己找出代码出了问题。否则,你的问题中没有足够的信息。

这是调试的第一步。您已经发现内存中的一个值正在被更改的明确指示。您在地址0x7fffffffdc60处发现了一个具体对象managed_device,它包含一个以某种方式更改的值。

让我使用一个简单完整的程序:

#include <stdio.h>
int *p;
void f() {
  ++*p;
}
int main() {
  int i = 3;
  p = &i;
  printf("%dn", i); // i is 3 here.
  f();
  printf("%dn", i); // Huh? i is 4 here.
}

当然,i在这个程序中发生变化的原因是非常明显的,但我们假设我完全忽略了它。

如果我在第13行设置一个断点(对f的调用),并检查i,我会发现它仍然是3

断点1,测试时的主()。cc:1313f();(gdb)p i$1=3

这并不奇怪。我已经确定,在未来的某个未知时刻,这个值会发生变化,我只是不知道什么时候。

我现在可以使用watch指令来监控变量的变化:

(gdb)手表i硬件观察点2:i

然后继续执行:

(gdb)续继续。硬件观察点2:i旧值=3新值=4f()在测试时。cc:77}(gdb)bt#测试时为0 f()。cc:7#测试时主()中有1 0x004011e9。cc:13

现在,我看到修改i的代码刚好在f的右大括号之前。

这就是您需要对自己的代码执行的操作。它将比这个简单的例子更复杂一些,但您也应该能够将它用于自己的代码。