[英]return pointer rather than vector::iterator and convert vector::iterator to pointer
i have a function that its return type is "vector::iterator" in below: 我有一个函数,其返回类型为“ 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();
}
the question is this, how to convert its return value to a pointer rather than of std::vector iterator? 问题是,如何将其返回值转换为指针而不是std :: vector迭代器?
i should be convert it for use to kernel in CUDA because we couldn't use vector or its iterator in CUDA 我应该将其转换为在CUDA中使用,因为我们不能在CUDA中使用vector或其迭代器
This is my way: 这是我的方式:
__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;
}
for work in kernel, for example: 用于内核工作,例如:
__global__ kernel void kernel . . .
.
.
unsigned int* d_h = foo( , ,)
.
.
but it's wrong and doesn't work, how to could i do it? 但这是错误的并且不起作用,我该怎么办? Thanks, 谢谢,
You can do &(*it)
which will provide a pointer to the element that the iterator refers to. 您可以执行&(*it)
,它将提供指向迭代器引用的元素的指针。 Use std::addressof(*it)
in generic code over std::vector<T>
if you don't know if operator&
has been overloaded by evil users. 如果您不知道operator&
是否已被恶意用户重载,请在通用代码中使用std::addressof(*it)
std::vector<T>
。
If with converting you mean rewriting the code without using vectors, but using arrays instead, I'd propose the following adjustments to your code: 如果进行转换意味着不使用向量而是使用数组来重写代码,则建议对代码进行以下调整:
__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.
}
The main issue in your code was that declaration unsigned int *a,b;
您代码中的主要问题是声明unsigned int *a,b;
creates a pointer a
to an unsigned int
and an unsigned int
variable b
, but not two pointers. 创建一个指针a
到一个unsigned int
和unsigned int
变量b
,但不是两个指针。
The second issue was the line res = &tmp;
第二个问题是行res = &tmp;
( by the way, its indenting is misleading. Fortunately gcc 6 will warn you in future ). ( 顺便说一下,它的缩进具有误导性。幸运的是, gcc 6将来会警告您 )。 This caused you to return the address of a temporary variable. 这导致您返回一个临时变量的地址。 But a temporary variable is destroyed as soon as you return from the function, so your returned pointer will point to a nowhere place (UB in perspective). 但是,从函数返回后,临时变量将被销毁,因此返回的指针将指向无处(透视图为UB)。
You can in principle use &*i
to get a pointer to the iterator's element, and hence the underlying vector data, but that won't help you here. 原则上,您可以使用&*i
获取指向迭代器元素的指针,从而获取指向底层矢量数据的指针,但这在这里无济于事。
Your first function is broken, as it returns an iterator into a vector whose lifetime ends when the function returns. 您的第一个函数已损坏,因为它将迭代器返回到向量中,该向量的寿命在函数返回时结束。
To fix that, you could take the vector by reference, 要解决此问题,您可以通过参考获取向量,
vector<unsigned int>::iterator foo(unsigned int arg, vector<unsigned int>& arr)
{
return arg == 2 ? arr.begin() + arr[1] : arr.begin();
}
but indexing is more robust than iterating and behaves well with const-ness: 但是索引比迭代更健壮,并且在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);
(Iterators are for iterating – they're meant to be transient and short-lived. (迭代器用于迭代 -迭代器是瞬时且短暂的。
You shouldn't use them as a kind of generalised pointer.) 您不应该将它们用作一种广义的指针。)
The CUDA code returns an equally wrong pointer to an automatic local variable when it should return a pointer into arr
: 当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.