[英]return pointer rather than vector::iterator and convert vector::iterator to pointer
我有一個函數,其返回類型為“ vector :: iterator”,如下所示:
vector<unsigned int>::iterator foo(unsigned int arg, vector<unsigned int> arr, vector<unsigned int> M)
{ if (arg == 0)
return arr.begin();
else if (arg == 2)
return arr.begin() + arr[arg - 1];
else
return arr.begin();
}
問題是,如何將其返回值轉換為指針而不是std :: vector迭代器?
我應該將其轉換為在CUDA中使用,因為我們不能在CUDA中使用vector或其迭代器
這是我的方式:
__host__ __device__ unsigned int* foo(unsigned int arg, unsigned int* arr, unsigned int* M)
{
unsigned int* res, tmp;
if (arg == 0)
tmp = arr[0];
else if (arg == 2)
tmp = arr[0] + arr[arg - 1];
else
tmp = arr[0];
res = &tmp;
return res;
}
用於內核工作,例如:
__global__ kernel void kernel . . .
.
.
unsigned int* d_h = foo( , ,)
.
.
但這是錯誤的並且不起作用,我該怎么辦? 謝謝,
您可以執行&(*it)
,它將提供指向迭代器引用的元素的指針。 如果您不知道operator&
是否已被惡意用戶重載,請在通用代碼中使用std::addressof(*it)
std::vector<T>
。
如果進行轉換意味着不使用向量而是使用數組來重寫代碼,則建議對代碼進行以下調整:
__host__ __device__ unsigned int* foo(unsigned int arg, unsigned int* arr, unsigned int* M)
{
unsigned int *res, *tmp; // attention * is per item !!
if (arg == 0)
tmp = arr; // return a pointer to the begining
else if (arg == 2)
tmp = arr + arr[arg - 1]; // you need to make pointer arithmetic like in the original code iterator arithmetics
else
tmp = arr; // keep it simple
return tmp; // note that you don't need res.
}
您代碼中的主要問題是聲明unsigned int *a,b;
創建一個指針a
到一個unsigned int
和unsigned int
變量b
,但不是兩個指針。
第二個問題是行res = &tmp;
( 順便說一下,它的縮進具有誤導性。幸運的是, gcc 6將來會警告您 )。 這導致您返回一個臨時變量的地址。 但是,從函數返回后,臨時變量將被銷毀,因此返回的指針將指向無處(透視圖為UB)。
原則上,您可以使用&*i
獲取指向迭代器元素的指針,從而獲取指向底層矢量數據的指針,但這在這里無濟於事。
您的第一個函數已損壞,因為它將迭代器返回到向量中,該向量的壽命在函數返回時結束。
要解決此問題,您可以通過參考獲取向量,
vector<unsigned int>::iterator foo(unsigned int arg, vector<unsigned int>& arr)
{
return arg == 2 ? arr.begin() + arr[1] : arr.begin();
}
但是索引比迭代更健壯,並且在const-ness下表現良好:
int foo(unsigned int arg, const vector<unsigned int>& arr)
{
return arg == 2 ? arr[1] : 0;
}
vector<unsigned int>::iterator it = myvector.begin() + foo(arg, myvector);
vector<unsigned int>::const_iterator cit = myvector.cbegin() + foo(arg, myvector);
(迭代器用於迭代 -迭代器是瞬時且短暫的。
您不應該將它們用作一種廣義的指針。)
當CUDA代碼應將指針返回到arr
時,它會返回同樣錯誤的指向自動局部變量的指針:
__host__ __device__ unsigned int* foo(unsigned int arg, unsigned int* arr, unsigned int* M)
{
return arg == 2 ? arr + arr[1] : arr;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.