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)

Вы разыменовываете указатель, который не был выделен, поэтому он недействителен. Попытка получить доступ к чему-либо таким способом приведет к неправильному доступу.

У вас есть (как минимум) два варианта, чтобы это исправить:

  1. после того, как вы выделили место для cpu_pointsВы можете выполнить другой cudaMallocHost распределение на cpu_points->Points
  2. Если вы знаете размер 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.

Другие вопросы по тегам