我想構建一個nx,ny,nz約爲200的3D nx * ny * nz矩陣,所以我必須使用動態分配,並且因爲我有很多這些矩陣,所以我需要以它使用的方式構建這些矩陣儘可能少的內存我怎麼能做到這一點,如何建立連續的形式?動態分配內存的3d陣列,使用最小的內存,並在C + +的連續形式?
回答
您可以圍繞std::vector
編寫一個包裝,並重載operator()
來訪問矩陣元素。元素連續存儲在1D std::vector
中,operator()
將3D索引轉換爲std::vector
中的1D索引。如果矩陣是2D,這是怎麼從2D到1D映射將如下所示:
| 1 2 3 |
| 4 5 6 | ---> [1 2 3 4 5 6 7 8 9]
| 7 8 9 |
這種排序被稱爲row major。
下面是重載operator()
到3D指數轉換成一排,主要的一維指數類的例子:
#include <iostream>
#include <vector>
template <class T>
class Matrix3D
{
public:
Matrix3D(size_t m, size_t n, size_t o)
: m_(m), n_(n), o_(o), data_(m*n*o) {}
T& operator()(size_t i, size_t j, size_t k)
{
return data_[(i * n_ * o_) + (j * o_) + k];
}
const T& operator()(size_t i, size_t j, size_t k) const
{
return data_[(i * n_ * o_) + (j * o_) + k];
}
private:
std::vector<T> data_;
size_t m_, n_, o_;
};
int main()
{
Matrix3D<float> m(4, 3, 2);
m(0,0,0) = 12.3f;
m(3,2,1) = 45.6f;
std::cout << m(0,0,0) << " " << m(3,2,1) << "\n";
}
的Boost.MultiArray庫本質上是做同樣的事情,因爲這(和更多),但可可用於任何N維
糟糕,應該是Boost.MultiArray,而不是Boost.MultiIndex。 – 2012-03-18 17:40:59
您的代碼有分段錯誤錯誤 – peaceman 2012-03-18 18:46:03
它在我的機器和Ideone.com上運行良好。我甚至嘗試過使用'vector
如果尺寸在編譯時已知,您可以使用new
來分配對象,但我可能會把它放在一個結構中,因爲我在陣列和指針上保持混合類型(我幾乎沒有直接使用它們):
struct array3d {
double array[200][200][200];
};
std::auto_ptr<areay3d> array(new array3d);
顯然,數組維度可以成爲模板參數。
如果僅在運行時確定尺寸,則需要分配一個連續的數組double
並自己進行數組下標計算。如果類可以訪問元素,這可能也會成爲一個集合:3d數組的下標運算符將返回對2d數組的引用等。std::valarray<double>
旨在幫助完成此操作,並且此類提升類也是如此。
看到這個問題如何使用'std :: valarray'來表示一個連續的二維矩陣:http://stackoverflow.com/questions/2187648/how-can-i-use-a -stdvalarray-store-manipulation-a-contiguous-2d-array – 2012-03-18 17:30:48
std :: auto_ptr被棄用... – 2012-03-18 20:07:05
@RobertMason:的確如此。但是,它可用於所有當代C++實現,不同於'std :: unique_ptr
使用C++ 11:
template<typename T,size_t M,size_t N,size_t O>
using Matrix3D = std::array<std::array<std::array<T,O>,N>,M>;
std::unique_ptr<Matrix3D<double,200,200,200>> mat(new Matrix3D<double,200,200,200>);
(*mat)[m][n][o] = 10.0;
如果你寫一個make_unique
功能VA聲明可變結構變爲:
auto mat = std::make_unique<Matrix3D<double,200,200,200>>();
所以整個節目看起來像:
#include <memory> // std::unique_ptr for convenient and exception safe dynamic-memory management
#include <array> // std::array because it behaves much better than raw arrays
template<typename T,size_t M,size_t N,size_t O>
using Matrix3D = std::array<std::array<std::array<T,O>,N>,M>;
// A simple `make_unique`
template<typename T,typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
int main() {
auto mat = make_unique<Matrix3D<double,200,27,200>>();
(*mat)[199][26][199] = 10.0; // store 10.0 in the last element
}
請記住,這是C++ 11,和一些編譯器還沒有實現所有的功能我正在使用。特別是我所知道的唯一支持模板別名的發佈編譯器(using Matrix3D =
行)是鏗鏘3.0。 GCC的下一個版本將支持它。在GCC和Clang中均支持可變模板(用於實現make_unique
),但在VS11中不支持MSVC。
下面是一個使用只有廣泛的支持* C++ 11功能版本:
#include <memory>
#include <array>
template<typename T,size_t M,size_t N,size_t O>
struct Matrix3D {
std::array<std::array<std::array<T,O>,N>,M> array;
};
// A simple `make_unique` that supports only zero-argument construction.
template<typename T>
std::unique_ptr<T> make_unique() {
return std::unique_ptr<T>(new T);
}
int main() {
auto mat = make_unique<Matrix3D<double,200,27,200>>();
mat->array[199][26][199] = 10.0; // store 10.0 in the last element
}
*
獲得廣泛支持的手段至少GCC和MSVC的最新版本。
OP希望矩陣元素連續存儲。這些元素是否會與此解決方案連續存儲? – 2012-03-18 17:35:13
@EmileCormier是的,元素是連續的。 – bames53 2012-03-18 17:38:11
根據這個(http://stackoverflow.com/questions/8262963/stdarray-alignment),'std :: array'可以在數組元素之後留下填充。所以'std :: array
- 1. 用於陣列的C++動態內存分配
- 2. 動態內存分配與陣列
- 3. c內存分配和陣列陣列
- 4. 動態內存分配在C++上的動態分配內存中
- 5. 使用動態分配的內存C++乘以矩陣
- 6. 連續內存分配
- 7. 分配連續內存
- 8. 動態內存分配C中的陣列
- 9. 動態內存分配和使用C
- 10. 動態內存分配
- 11. C++中的動態內存分配
- 12. GPU上的連續內存分配
- 13. 連續內存塊的動態分配(malloc)
- 14. c#3d應用程序內存分配
- 15. 動態內存分配
- 16. 裝配多個陣列內存分配
- 17. 二維數組的連續內存分配---釋放內存
- 18. 陣列內存分配
- 19. Ç2D陣列內存分配
- 20. 動態內存分配在C?
- 21. 爲大陣列分配內存? [C++]
- 22. 爲2d陣列分配內存c
- 23. 使用指針爲C中的3D數組分配內存?
- 24. 矩陣的內存分配
- 25. 在連續的內存塊中分配objective-c對象
- 26. 使用fgets +動態內存分配
- 27. 推力動態分配的內存陣列
- 28. 瞭解具有動態內存分配的2D陣列
- 29. C中矩陣的內存分配
- 30. 指針陣列的內存分配
這些稀疏矩陣? – 2012-03-18 16:29:34
你可能會考慮[Boost.MultiArray](http://www.boost.org/doc/libs/1_49_0/libs/multi_array/doc/index.html)。 – 2012-03-18 16:30:25
元素是雙倍的。 – peaceman 2012-03-18 16:36:05