今天用CUDA实现图像负片效果
目录
2. exited with code -1073740940 (0xc0000374)
问题描述
1. 计算结果有偏差
2. exited with code -1073740940 (0xc0000374)
问题分析
1. 计算结果有偏差
cudaError_t supplementPix(uchar *c, const uchar *a, unsigned int size);
__global__ void supplementKernel(int *c, const int *a)
{
int i = threadIdx.x;
c[i] = 255 - a[i]; // 常量计算会导致运算错误,比如 255 - 1=253
}
运行结果
后来创建全255、CV_8UC3的cv::Mat对象,提取data数组作为被减数
cv::Mat mask = cv::Mat(rows, cols, CV_8UC3, cv::Scalar::all(255));
// 常量计算会导致运算错误,比如 255 - 1=253
// 必须使用数组传参
const uchar* maskData = mask.data;
运行结果正确:
但是出现了新的问题
2. exited with code -1073740940 (0xc0000374)
查找相关信息
《vs报错未加载wntdll.pdb,ntdll.dll0xC0000374: 堆已损坏》(https://blog.youkuaiyun.com/luoye2333/article/details/89087530)
开始调试
调试之后发现是在调用CUDA方法之后导致的内存错误,致使程序结束时销毁对象时发生错误。
检查CUDA调用函数
cudaError_t supplementPix(uchar *c, const uchar *a, const uchar *b, unsigned int size){
cudaStatus = cudaMalloc((void**)&dev_c, size * sizeof(int));
cudaStatus = cudaMalloc((void**)&dev_a, size * sizeof(int));
cudaStatus = cudaMalloc((void**)&dev_b, size * sizeof(int));
cudaStatus = cudaMemcpy(dev_a, a, size * sizeof(int), cudaMemcpyHostToDevice);
cudaStatus = cudaMemcpy(dev_b, b, size * sizeof(int), cudaMemcpyHostToDevice);
cudaStatus = cudaMemcpy(c, dev_c, size * sizeof(int), cudaMemcpyDeviceToHost);
}
发现是在修改模板代码时候,将int改为uchar,改漏了sizeof(int)
解决方案
修改之后,运行结果(成功)
综述
当程序返回值为 exited with code -1073740940 、调式错误提示0xc0000374 ntdll.dll堆已损坏 时候说明是内存泄漏问题,
尤其是由此导致程序结束时销毁对象(即release())时的错误