0

Я не могу понять, что вызывает проблему. В последней строке появляется сообщение об ошибке «Ошибка доступа к записи». Я неправильно распределяю память?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 

ответ

2

У вас есть 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 создан таким образом, что предлагается второй метод. Если вы перейдете первым способом, ваш расчет bundle_size неверен. В любом случае, с помощью любого из методов, проще просто вычислить bundle_size как sizeof(BUNDLE).

Чтобы быть ясным, здесь нет ничего специфичного для CUDA (ошибка будет присутствовать, например, если вы использовали malloc вместо cudaMallocHost). Проблема уходит корнями в базовое понимание C, а не CUDA.

+0

Благодарим вас за подробный урок. Это имеет смысл. Я, очевидно, не реализовал этот уровень сложности в C, поэтому столкнулся с CUDA. Как вы предположили, второй вариант подходит хорошо, вероятно, также экономит время распределения. – Nenu

Смежные вопросы