首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++以内存安全的方式使用给定向量的大小创建2D数组。

C++以内存安全的方式使用给定向量的大小创建2D数组。
EN

Stack Overflow用户
提问于 2015-04-06 14:05:56
回答 4查看 389关注 0票数 2

如何实现以下目标:

代码语言:javascript
运行
复制
std::vector<int> vec = { 1, 2, 3 };
const int N = vec.size();
// Now create NxN 2D array.

首先,我知道我可以用new来完成它,但是我必须记住以后删除它,如果可能的话,我不想处理内存的分配问题。

其次,我不能声明堆栈上的2D数组,因为N不是(在本例中也不能)常量表达式。(无论如何,我使用的是VS2013,它不支持constexpr。)

第三,我不能(或者可能不知道如何)使用std::array,因为显然“局部变量不能用作非类型参数”。(我从VS2013编译对话中复制-粘贴了这一点,但对这一点了解甚少)。

第四,我正在考虑使用unique_ptr。问题是,我知道如何对一维数组使用unique_ptr,比如std::unique_ptr<int> arr{ new int[N] },但不知道如何对2D数组这样做。

最后,我知道我总是可以围绕堆上创建的C样式数组编写自己的薄包装器,也可以编写自己的2D数组类。但是,在C++ (C++11)中是否有一种本地或标准库方法来实现这一点呢?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-04-06 19:21:49

std::experimental::array_view是一个在填充缓冲区上具有动态大小界限的n维数组的视图.

因此,一种方法是创建一个连续缓冲区(例如,一个std::vector<T>或一个std::unique_ptr<T[]> ),然后将一个array_view<T,2>封装在它周围。

通过视图对象进行访问,它将具有从数组中期望的操作。存储与查看存储的方式是分开管理的。

为1和2维情况编写此array_view的简化版本并不困难。但是结果是,您的代码具有很高的性能,并且在使用时非常清晰。胶水代码(对于array_view)可能有点棘手,但是一旦测试过之后,它应该是可靠的:类似的构造可能很快就会添加到std中,这意味着它不会在很长一段时间内变得模糊不清。

在我的经验中,一旦我有了一个可靠的array_view类型,我就会使用它代替以前使用std::vector传递数据束的地方(效率不高)。

如果您想编写自己的代码,我将跳过有关界和索引的部分,只需实现切片--在二维[]array_view返回第1维array_view,而在第1维array_view上实现[]返回T&

票数 2
EN

Stack Overflow用户

发布于 2015-04-06 15:11:31

我建议你给它写一堂课。

下面的示例: set()在设置值之前调整它的大小。运算符[]返回该行的列向量,因此当应用运算符[]时,它返回所需的值。如果你发现任何问题,请告诉我;)

代码语言:javascript
运行
复制
class 2DVector {
 std::vector<std::vector<int>> m_items;

 void set(int value, size_t row, size_t column) {
   for (int i=m_items.size(); i<=row; i++) {
      m_items.push_back(std::vector<int>());
   }
   for (int i=0; i<m_items.size(); i++) {
      for (int j=m_items[i].size(); j<=column; j++) {
      m_items[i].push_back(0);
   }
   m_items[row][column] = value;
 }

 std::vector<int> &operator [](size_t index) {
   return m_items[index];
 }
}

用法:

代码语言:javascript
运行
复制
2DVector v;
v.set(200, 0, 0);
v.set(201, 1, 0);
std::cout << v[0][0]; //prints 200
std::cout << v[1][0]; //prints 201
票数 1
EN

Stack Overflow用户

发布于 2015-04-08 00:47:21

这样做的标准库方法是:

代码语言:javascript
运行
复制
std::vector< std::vector<int> > vec2d (vec.size(), vec);

它将使用来自vec的值初始化每一行。如果你不想这样做,那就放弃最后的论点。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29472890

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档