我有一个二维数组,我使用new来动态分配。
问题是我想将内存分配为一个连接的块而不是分开的块,以提高处理速度。
是否有人知道是否可以使用new执行此操作,或者我是否必须使用malloc?
这是我的代码:
A = new double*[m];
for (int i=0;i<m;i++)
{
A[i]= new double[n];
}
此代码导致分段错误
phi = new double**[xlength];
phi[0] = new double*[xlength*ylength];
phi[0][0] = new double[xlength*ylength*tlength];
for (int i=0;i<xlength;i++)
{
for (int j=0;j<ylength;j++)
{
phi[i][j] = phi[0][0] + (ylength*i+j)*tlength;
}
phi[i] = phi[0] + ylength*i;
}
答案 0 :(得分:3)
您可以分配一个大块并适当地使用它,如下所示:
double* A = new double[m*n];
for (int i=0; i<m; i++) {
for (int j=0; j<n; j++) {
A[i*n+j] = <my_value>;
}
}
除了使用new
之外,您可以使用malloc
- 除了new
必须与delete
和malloc()
一起发布外,没有太大区别与free()
一起发布。
<强> UPDATE1 强>: 您可以按如下方式创建“true”二维数组:
double** A = new double*[m];
double* B = new double[m*n];
for (int i=0; i<m; i++) {
A[i] = B + n*i;
}
for (int i=0; i<m; i++) {
for (int j=0; j<n; j++) {
A[i][j] = <my_value>;
}
}
请务必最后同时发布A
和B
。
<强> UPDATE2 强>:
根据大众要求,您可以创建“真正的”三维数组(尺寸为m
x n
x o
):
double*** A = new double**[m];
double** B = new double*[m*n];
double* C = new double[m*n*o];
for (int i=0; i<m; i++) {
for (int j=0; j<n; j++) {
B[n*i+j] = C + (n*i+j)*o;
}
A[i] = B + n*i;
}
for (int i=0; i<m; i++) {
for (int j=0; j<n; j++) {
for (int k=0; k<o; k++) {
A[i][j][k] = <my_value>;
}
}
}
这使用2个相对较小的“索引”数组A
和B
以及数据数组C
。像往常一样,这三个都应该在使用后释放。
将这个扩展到更多维度是留给读者的练习。
答案 1 :(得分:0)
使用malloc
无法对new
做任何事情(尽管反过来并不成立)。但是,如果您已经在单独的块中分配了内存,则必须分配新的(连续的)内存才能获得连接的块(使用malloc
或new
)。您显示的代码会分配m
个非连续n
大小的块。要获得具有连续内存的数组,您需要
int MN = m*n;
B = new double[MN];
for (int i=0; i<MN; ++i)
B[i] = A[ i/N ] [ i%N ];
答案 2 :(得分:0)
好的,如果任务是维护单个内存块,但保持[] []解决它的方法,我会尝试一些类的技巧。第一个是内部代理:
class CoordProxy
{
private:
int coordX;
int arrayWidth;
int * dataArray;
public:
CoordProxy(int * newArray, int newArrayWidth, int newCoordX)
{
coordX = newCoordX;
arrayWidth = newArrayWidth;
dataArray = newArray;
}
int & operator [](int newCoordY)
{
return (dataArray[newCoordY * arrayWidth + coordX]);
}
};
class CoordsWrapper
{
private:
int * dataArray;
int width;
int height;
public:
CoordsWrapper(int * newArray, int newWidth, int newHeight)
{
dataArray = newArray;
width = newWidth;
height = newHeight;
}
CoordProxy operator[] (int coordX)
{
return CoordProxy(dataArray, width, coordX);
}
};
int main(int argc, char * argv[])
{
int * a = new int[4 * 4];
ZeroMemory(a, 4 * 4 * sizeof(int));
CoordsWrapper w(a, 4, 4);
w[0][0] = 10;
w[0][1] = 20;
w[3][3] = 30;
std::for_each(&a[0], &a[4 * 4], [](int x) { printf("%d ", x); });
delete[] a;
}
注意,这不是时间效率,但是内存效率极高:使用4个整数和2个指针比原始类更多。
甚至更好,更快的解决方案,但你必须从[] []符号辞职,而不是(,)符号:
class CoordsWrapper2
{
private:
int * data;
int width;
int height;
public:
CoordsWrapper2(int * newData, int newWidth, int newHeight)
{
data = newData;
width = newWidth;
height = newHeight;
}
inline int & Data(int x, int y)
{
return data[y * width + x];
}
};
int main(int argc, char * argv[])
{
int * a = new int[4 * 4];
ZeroMemory(a, 4 * 4 * sizeof(int));
CoordsWrapper2 w(a, 4, 4);
w.Data(0, 0) = 10;
w.Data(0, 1) = 20;
w.Data(3, 3) = 30;
std::for_each(&a[0], &a[4 * 4], [](int x) { printf("%d ", x); });
delete[] a;
}
请注意内联指令。它建议编译器替换实际源代码的方法调用,这使得它更快一些。这种解决方案具有更高的内存效率,与经典索引相比,可以更少或同等时间效率。