我不喜欢过多地使用指针而且我总是使用stl工具。我已经遇到这种情况,我需要将int **传递给需要使用2d数组的int的第三方函数。我编写了以下函数,它创建了一个int * s向量来完成这项工作。我的问题是假设third_party函数不改变数组的结构并只访问数据条目,这样做是否安全。有更好的方法吗?
这是函数def:
void ConvertVectorVectorToIntStarStar(const std::vector<std::vector<int> >& v,vector<int*>* a) {
assert(a);
int n = v.size();
a->resize(n);
for(int i = 0; i < n; ++i)
(*a)[i] = (int*)(&v[i][0]);
}
这是用法:
vector<int*> p;
ConvertVectorVectorToIntStarStar(v, &p);
int** a = &p[0];
third_party_function(a);
答案 0 :(得分:3)
如何将
vector<vector<int>>
转换为int**
您无法简单地转换它。
vector<int>
向量的内部布局与int*
数组完全不相容。 : - )
以下是您的类型:
vector<vector<int>> v{{ 1, 2, 3 }, { 1, 2, 3 }, { 1, 2, 3 } };
int (*a)[] = { new int[3], new int[3], new int[3] };
您会注意到的第一件事是a
是int (*)[]
而不是int**
。当您使用a
时,它会衰减为int**
; int[][]
不会执行此操作。
让我们得到我们的第一级指针:
vector<int>* ptr1 = &v[0];
int** ptr2 = &a[0];
现在让我们看一下存储:
ptr1[0]
是vector<int>
ptr2[0]
是int*
int**
向量的数据。
然而,如果您不介意从头开始构建最外层的“索引”数组,那么您的方法基本上是合理的。这不是你似乎追求的零步过程。
而不是所有这些,我的建议是使用2D索引访问语义包装vector<int>
(长度宽度×高度)。如果您愿意,您可以使用int*
播放整个数据缓冲区。
感谢 Freenode ## c ++ :
template<typename T>
struct matrix
{
matrix(unsigned m, unsigned n)
: m(m), n(n), vs(m*n)
{}
T& operator()(unsigned i, unsigned j)
{
return vs[i + m * j];
}
private:
unsigned m, n;
std::vector<T> vs;
};
/* column-major/opengl: vs[i + m * j], row-major/c++: vs[n * i + j] */
答案 1 :(得分:2)
如果你需要演员表,有些事情是不对的:
(*a)[i] = (int*)(&v[i][0]);
我猜这应该真的读
(*a)[i] = const_cast<int*>(v[i].data());
否则代码看起来没问题就可以了:std::vector<T>
中的元素是连续的。
答案 2 :(得分:1)
而不是当前的代码...
void ConvertVectorVectorToIntStarStar(const std::vector<std::vector<int> >& v,vector<int*>* a) {
assert(a);
int n = v.size();
a->resize(n);
for(int i = 0; i < n; ++i)
(*a)[i] = (int*)(&v[i][0]);
}
我建议你做......
vector<int*> IntStarStarFrom( std::vector<std::vector<int>>& v)
{
int const n = static_cast<int>( v.size() );
assert( n > 0 );
vector<int*> a( n );
for(int i = 0; i < n; ++i)
{
assert( v[i].size() > 0 );
a[i] = &v[i][0];
}
return std::move( a );
}
免责声明:关闭袖口代码,不会被编制者的手触及。
断言表达了相关的安全问题。
向量的缓冲区保证是连续的,但是当它的大小为0时,IIRC是未定义的行为来索引向量。
使用代码,重新使用建议的功能替换:
vector<int*> p = IntStarStarFrom( v );
int** const a = &p[0];
third_party_function( a );
或者在评论中注明Mark Ransom,您现在可以在一行代码中执行此操作:
third_party_function(IntStarStarFrom(v).data());
答案 3 :(得分:1)
std::vector<std::vector<int> > vt;
// some code with vt..
std::vector<int *> vtp;
for (const std::vector<int> &vtr : vt)
vtp.push_back(const_cast<int *>(vtr.data()));
我没有测试,但我认为我运作良好