cudaFree();出错是怎么回事

程序是这样的
int* d_ipx;
cudaMalloc((void**)&d_ipx,sizeof(int)phantom_widexphantom_wideyphantom_widez);
cudaMemset(d_ipx,0,sizeof(int)phantom_widexphantom_widey
phantom_widez);
…………
cudaMemcpy(ipx,d_ipx,sizeof(int)phantom_widexphantom_widey*phantom_widez,cudaMemcpyDeviceToHost);(no error)
cudaFree(d_ipx);(invalid device pointer)
不明白为什么释放的时候会出错,哪位大侠指点下

你看一下cudaMalloc出错没?

分配空间的时候没有错,用cudaGetErrorString得到是no error。用Debug调试会出这种错误
First-chance exception at 0x75649617 in SP2010.exe: Microsoft C++ exception: cudaError at memory location 0x0014f4c8…
开始怀疑是数组越界,检查了半天没有能够越界的地方,后来程序改成
cudaMalloc((void**)&d_ipx,sizeof(int)phantom_widexphantom_wideyphantom_widez); (no error)
cudaMemset(d_ipx,0,sizeof(int)phantom_widexphantom_widey
phantom_widez);(no error)
cudaMemcpy(ipx,d_ipx,sizeof(int)phantom_widexphantom_widey*phantom_widez,cudaMemcpyDeviceToHost);(no error)
cudaFree(d_ipx);
printf(“%s \n”,cudaGetErrorString(cudaFree(d_ipx))); 显示 (invalid device pointer)
现在核函数中根本不用这个数组,分配了就释放都还是不行,郁闷了

[

你确定你在cudaFree(d_ipx)前,没有更改过d_ipx的值?无论是你有意还是无意的。比如:你的d_ipx放置在一个地方,而这个地方可以被你的上一步Device->Host的memcpy给覆盖掉?
你把你定义d_ipx和ipx的这两个地方给贴出来。

比如:这种小白行为(不是说你,别见怪哈), 可以轻松导致这个问题:
int* d_ipx;
int ipx[N]; (其中,N<phantom_widthphantom_heightphantom_depth)
然后cudaMalloc(…); (success)
然后cudaMemcpy(ipx,d_ipx,sizeof(int)phantom_widthphantom_height*phantom_depth,cudaMemcpyDeviceToHost); (success)
再然后cudaFree(d_ipx)就失败了,因为在上一步中,d_ipx已经被成功的覆盖了。

你给的代码有问题?能否分析一下?

[

有啊:
因为先定义了d_idx, 然后定义了idx, 一般情况下在堆栈里,d_idx要排在idx的后面(因为我们的x86机器堆栈是从高到低地址生长的), 这个时候,如果idx的长度不够,一个memcpy就会填满了idx后继续填,导致d_idx被从device copy过来的值给覆盖了。(如果楼主在这种情况下继续运行,从而更严重, 他很可能因为后续的堆栈中的其他内存,包括其他的局部变量甚至返回地址等都被破坏,以至于他可能还得到其他的异常)。这也是我们一直要求楼主贴代码的原因。

我再说一句:
一般只有两种情况你会得到无效的设备指针提示:
一个是,你的指针就是无效的。
第二个是,你的指针是有效的值,但是你调用cudaFree的线程不是你当初的那个线程了。这个样子也是这个错误的。

[

第二种情况导致设备内存释放失败的情况我遇到。就是怎么看device pointer都是没问题的,但就是不能释放。这是咋回事?后来发现,是因为在C#的析构函数里面,是无法释放的;不过如果手工的实现IDisposable, 然后在Dispose()函数里面手工释放是没有问题的。然后发现,因为C#的析构函数总是在GC线程里面执行的。而因为这个线程不是当初malloc设备内存(也就是绑定context)的那个线程,所以自然失败。

你看看你是哪种情况。我估计你是第一种。楼主用调试器看看设备指针的值是不是被改变了。

先谢谢各位的帮助哈,问题解决了,解决办法就是重启电脑:sweat: ,重启之后那个问题就没了,我不知道问题是怎么消失的,我把代码换回原来出错时候的代码,问题还是没了,我还在研究……。

[

额。。。。

问题解决了就好

[

请教第二种情况如何解决?

不明白:o