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

时间:2015-02-12 19:27:56

标签: c++ c++11

我遇到了一个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;
}

当它运行复制功能时,它有“分段错误”。

这是副本的def:

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。我无法弄清楚为什么这么开心?

感谢您给我一些建议。

1 个答案:

答案 0 :(得分:1)

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

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

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

#include <stdio.h>

int *p;

void f() {
  ++*p;
}

int main() {
  int i = 3;
  p = &i;
  printf("%d\n", i); // i is 3 here.
  f();
  printf("%d\n", i); // Huh? i is 4 here.
}

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

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

Breakpoint 1, main () at test.cc:13
13        f();
(gdb) p i
$1 = 3

那里不足为奇。而且我已经确定未来某个未知点的价值会发生变化,我只是不知道什么时候。

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

(gdb) watch i
Hardware watchpoint 2: i

然后继续执行:

(gdb) cont
Continuing.
Hardware watchpoint 2: i

Old value = 3
New value = 4
f () at test.cc:7
7       }
(gdb) bt
#0  f () at test.cc:7
#1  0x004011e9 in main () at test.cc:13

现在,我已经看到修改i的代码就在f的结束括号之前。

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