cudaMemcpy分段错误
我已经被这个错误困扰了很长一段时间所以我决定在这里发布它。
调用cudaMemcpy时发生此分段错误:
CurrentGrid->cdata[i] = new float[size];cudaMemcpy(CurrentGrid->cdata[i], Grid_dev->cdata[i], size*sizeof(float),\ cudaMemcpyDeviceToHost);
CurrentGrid
并且Grid_dev
分别指向grid
主机和设备上的类对象,在此上下文中i = 0。类成员cdata
是一个浮点类型指针数组。为了调试,这cudaMemcpy调用之前对的,我打印出来的每个元素的值Grid_Dev->cdata[i]
,地址CurrentGrid->cdata[i]
和Grid_dev->cdata[i]
和的价值size
,这一切看起来不错。但它仍然以“分段故障(核心转储)”结束,这是唯一的错误消息。cuda-memcheck只给出了“进程没有成功终止”。我目前无法使用cuda-gdb。关于去哪儿的任何建议?
更新:现在看来我已经通过cudaMalloc解决了这个问题,设备上的另一个浮点指针A和cudaMemcpy的Grid_dev-> cdata [i]的值为A,然后是cudaMemcpy A来主机。所以上面写的代码段变成:
float * A;cudaMalloc((void**)&A, sizeof(float));......cudaMemcpy(&A, &(Grid_dev->cdata[i]), sizeof(float *), cudaMemcpyDeviceToHost); CurrentGrid->cdata[i] = new float[size];cudaMemcpy(CurrentGrid->cdata[i], A, size*sizeof(float), cudaMemcpyDeviceToHost);
我之所以这样做是因为valgrind突然出现了“8号无效读取”,我认为这是指的Grid_dev->cdata[i]
。我用gdb再次检查它,打印出Grid_dev->cdata[i]
NULL值。所以我想即使在这个cudaMemcpy调用中也无法直接取消引用设备指针。但为什么 ?根据这个帖子底部的评论,我们应该能够在cudaMemcpy函数中取消引用设备指针。
另外,我不知道cudaMalloc和cudaMemcpy如何工作的基本机制,但我认为cudaMalloc是一个指针,比如A,我们实际上指定这个指针指向设备上的某个地址。通过cudaMemcpy Grid_dev->cdata[i]
到A,如上面的修改代码,我们重新分配指针A指向数组。那么,当它是cudaMalloced时,我们不会失去A指向的先前地址的轨道吗?这会导致内存泄漏吗?如果是的话,我应该如何妥善解决这种情况?谢谢!
作为参考,我将完整函数的代码放在下面发生此错误的代码中。
弑天下
相关分类