[英]Question about Dynamic memory allocation in C++ for 3D array
我想寫一個函數來創建一個 3D 矩陣,但是當我嘗試顯示它時遇到了問題,請幫助我,謝謝。
我的老師給了我他的代碼。他的代碼可以創建一個具有動態 memory 的二維數組,我想更改他的代碼以創建一個 3D 矩陣。 當我試圖顯示矩陣時,我意識到我創建的數組是一個二維數組,而且因為我剛開始使用 C++,所以我找不到我的錯誤。
/*<Array3D.h>*/
#pragma once
#ifndef _ARRAY_3D_H_
#define _ARRAY_3D_H_
//-----------------------------------------
#include <cassert>
#include <vector>
using namespace std;
template<typename T>
class Array3D
{
public:
typedef Array3D<T> _Myt;
Array3D()
: m_nRows(0)
, m_nCols(0)
, m_nDepths(0)
{}
Array3D(size_t r, size_t c,size_t d)
{
Resize(r, c, d);
}
//Allocating memory size
void Resize(size_t r, size_t c,size_t d)
{
if (r == m_nRows && c == m_nCols && d==m_nDepths) { return; }
bool bValid = r > 0 && c > 0 && d>0;
if (!bValid) return;
m_nRows = r;
m_nCols = c;
m_nDepths = d;
m_v.resize(m_nRows * m_nCols * m_nDepths);
}
const T* operator[](size_t r) const
{
assert(r >= 0 && r < m_nRows);
return &(*(m_v.begin() + (r * m_nCols * m_nDepths)));
}
T* operator[](size_t r)
{
assert(r >= 0 && r < m_nRows);
return &(*(m_v.begin() + (r * m_nCols * m_nDepths)));
}
//Gets the start position of a one-dimensional array
const T* GetRawPointer() const { return &(m_v[0]); }
T* GetRawPointer() { return &(m_v[0]); }
long Rows() const
{
return static_cast<long>(m_nRows);
}
long Cols() const
{
return static_cast<long>(m_nCols);
}
long Depths() const
{
return static_cast<long>(m_nDepths);
}
long TotalSize() const
{
return static_cast<long>(m_nRows * m_nCols * m_nDepths);
}
void ClearUp()
{
m_nRows = 0;
m_nCols = 0;
m_nDepths = 0;
m_v.clear();
}
bool IsEmpty() const { return m_v.empty(); }
protected:
vector<T> m_v;// Internally a one-dimensional is used
size_t m_nRows;
size_t m_nCols;
size_t m_nDepths;
};
<Matrix3D.h>
#pragma once
#include "Array3D.h"
class Matrix3D
{
public:
Matrix3D(int r = 0, int c = 0, int d = 0)
{
setSize(r, c, d);
}
void setSize(int r, int c, int d) { m_data3D.Resize(r, c, d); }
void clear() { m_data3D.ClearUp(); }
int rows() const { return m_data3D.Rows(); }
int cols() const { return m_data3D.Cols(); }
int Depths() const { return m_data3D.Depths(); }
void display() const;
//Operator Overloading
float* operator[](int rIndex) { return m_data3D[rIndex]; }
const float* operator[](int rIndex) const { return m_data3D[rIndex]; }
private:
Array3D<float> m_data3D;
};
#include "Matrix3D.h"
#include <iostream>
using namespace std;
void Matrix3D::display() const
{
if (m_data3D.IsEmpty())
{
cout << "empty matrix" << endl;
return;
}
cout << "------------------------" << endl;
const int rows = this->rows();
const int cols = this->cols();
const int Depths = this->Depths();
cout << rows << "x" << cols << "x" << Depths << endl;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
for(int k = 0 ;k < Depths; k++)
{
cout << m_data3D[i][j][k] << ' '; /*This section will pose an error "E0142"*/
}
cout << endl;
}
}
}
我猜你的老師 class 是Array2D
並且你主要只是將m_nDepths
添加到它以將它變成Array3D
。 如果這個假設不正確,那么我在這里的回答很可能是完全錯誤的。
但如果我是對的,那么他的operator[]
看起來像:
T* operator[](size_t r)
{
assert(r >= 0 && r < m_nRows);
return &(*(m_v.begin() + (r * m_nCols)));
}
這意味着當您執行m_data2D[i][j]
時,第一個[i]
應用於Array2D
。 如上所示,這將返回一個指針(在您的情況下可能是float*
)。 然后將[j]
應用於此指針,這會產生一些指針算術,從而產生float
(對於float *x
; x[y]
表示*(x+y)
)。
換句話說,你的老師將他的二維數組逐行存儲在一維數組中,當你[]
進入它時,你會得到一個指向正確行的指針,然后你可以進一步[]
進入。
這一切都很好。
問題是當你向它添加第三個維度並嘗試相同的方法時:第一個[]
仍然返回一個float*
(但這次是正確的二維矩陣),第二個[]
返回一個float
(二維矩陣的正確行),第三個[]
嘗試應用於float
- 它不能,你會得到錯誤。
有兩種方法可以解決此問題:
Array3D::operator[]
的返回類型以返回某種二維數組類型,其operator[]
的工作方式與原始Array2D
。operator[]
方法並將其替換為采用 3 arguments 的成員 function 並立即返回正確的元素。 我想這是我自己更喜歡的。對於第二個選項,類似於(未測試,我很有可能弄亂了參數的順序):
T element(size_t x, size_t y, size_t z) const
{
assert(x >= 0 && x < m_nDepths);
assert(y >= 0 && y < m_nCols);
assert(z >= 0 && z < m_nRows);
return *(m_v.begin() + (x * m_nCols * m_nDepths +
y * m_nCols +
z));
}
T& element(size_t x, size_t y, size_t z)
{
assert(x >= 0 && x < m_nDepths);
assert(y >= 0 && y < m_nCols);
assert(z >= 0 && z < m_nRows);
return *(m_v.begin() + (x * m_nCols * m_nDepths +
y * m_nCols +
z));
}
結果cout << m_data3D[i][j][k] << ' ';
進入cout << m_data3D.element(i,j,k) << ' ';
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.