CUDA: указатель на доступ к памяти указателя
Я не могу понять, что является причиной проблемы. В последней строке я получаю сообщение об ошибке доступа к месту записи. Я не правильно распределяю память?
typedef struct {
doubleXYZW cen_sum; //struct with 4 doubles
double STS[6];
XYZW *Points;// //struct with 4 floats
}BUNDLE;
BUNDLE *cpu_data = NULL;
size_t bundle_size = NUM_POINTS * sizeof(XYZW) + sizeof(doubleXYZW) + 6*sizeof(double);
HANDLE_ERROR(cudaMallocHost((BUNDLE**)&cpu_data, bundle_size));
//error in the next line
cpu_data->Points[0].x = 0; //x is the first element in the XYZW struct
1 ответ
У вас есть 2 распределения, которые необходимо выполнить, и вы выполняете только одно из них.
Вы выделяете некоторое хранилище для cpu_data
указатель, но вы не выделили хранилища для Points
указатель. Поэтому при разыменовании очков:
cpu_data->Points[0].x = 0;
^ ^
| this dereferences the Points pointer (NOT allocated!)
|
this dereferences the cpu_data pointer (allocated)
Вы разыменовываете указатель, который не был выделен, поэтому он недействителен. Попытка получить доступ к чему-либо таким способом приведет к неправильному доступу.
У вас есть (как минимум) два варианта, чтобы это исправить:
- после того, как вы выделили место для
cpu_points
Вы можете выполнить другойcudaMallocHost
распределение наcpu_points->Points
Если вы знаете размер
Points
массив (кажется, что вы делаете -NUM_POINTS
) тогда вы могли бы просто статически выделить на это:typedef struct { doubleXYZW cen_sum; //struct with 4 doubles double STS[6]; XYZW Points[NUM_POINTS];// //struct with 4 floats }BUNDLE;
Обратите внимание, что ваш bundle_size
расчет выполнен таким образом, что предлагается 2-й метод. Если вы идете с первым методом, ваш bundle_size
расчет неверный. В любом случае, с любым методом проще просто вычислить bundle_size
как sizeof(BUNDLE)
,
Для ясности, здесь нет ничего специфичного для CUDA (ошибка будет присутствовать, например, если вы использовали malloc
вместо cudaMallocHost
). Проблема коренится в базовом понимании C, а не в CUDA.