0

我的问题的描述在下面的代码中。

class A
{
public :
        __device__ __host__ virtual void foo() = 0;
        __device__ __host__ void foo2()
        {
                //something to do...
        }
};

class B : public A
{
public :
        __device__ __host__ B()
        { }
        //implementing virtual method foo from A
        void foo()
        {
                //something to do...
        }
};

__global__ void Test(A* ptr_device)
{
        ptr_device->foo2(); //it's okey
        ptr_device->foo(); //ERROR !!!
}

void main()
{
        B* b_host = new B();

        A* a_host = (A*)malloc(sizeof(A));
        memcpy(a_host, b_host, sizeof(A));

        a_host->foo();
        a_host->foo2();
        //it's okey

        A* a_device;
        cudaMalloc((void**)&a_device, sizeof(A));
        cudaMemcpy(a_device, a_host, sizeof(A), cudaMemcpyHostToDevice);
        Test<<<1, 1>>>(a_device);
}

问题是当我想在内核上调用 A 类的虚拟方法时。首先,我创建一个对象 B,然后为 A 对象分配空间并将 B 复制到 A。在主机代码上它工作正常,但在设备代码中它在调用 foo 方法时出错

4

1 回答 1

1

您不能只是memcpy周围的非 POD 对象并期望它们工作,您在这里调用了相当多的 UB。

在您的情况下发生的情况很可能是该对象有一些被复制的虚拟表指针,但在其他执行环境中没有任何意义,因为它几乎肯定不会指向那里存在的虚拟表(假设它甚至有一个)。

于 2013-02-22T13:18:59.813 回答