簡體   English   中英

返回指針而不是vector :: iterator並將vector :: iterator轉換為指針

[英]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 intunsigned 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM