English 中文(简体)
C++ 3d阵列——一个线上的动态记忆分配
原标题:C++ 3d array - dynamic memory allocation aligned in one line

i 有一个非常棘手的问题,可能没有任何实际用途,但回答者我很多。 我今天试图用阵列和如何利用这部法典为记忆而分配的微薄片。

int ***c;
int size_x = 0;
int size_y = 0;
int size_z = 0;

cout << "Enter x: " << endl;
cin >> size_x;
cout << "Enter y: " << endl;
cin >> size_y;
cout << "Enter z: " << endl;
cin >> size_z;

c = new int**[size_x];
for (int i = 0; i < size_x; ++i) {
    *(c+i) = new int*[size_y];
    for (int j = 0; j < size_y; ++j) {
        *(*(c+i)+j) = new int[size_z];
    }
}

for (int i = 0; i < size_x; ++i) {
    for (int j = 0; j < size_y; ++j) {
        for (int k = 0; k < size_z; ++k) {
            cout << (*(*(c+i)+j)+k) << endl;
            //cout << &c[i][j][k] << endl;
        }
    }
}

delete [] c;

i 进入时:3、2和4, 即获得以下产出:

0x100100a60 0x100100a64 0x100100a68 0x100100a6c 0x100100a70 0x100100a74 0x100100a78 0x100100a7c 0x100100a90 0x100100a94 0x100100a98 0x100100a9c 0x100100aa0 0x100100aa4 0x100100aa8 0x100100aac 0x100100ac0 0x100100ac4 0x100100ac8 0x100100acc 0x100100ad0 0x100100ad4 0x100100ad8 0x100100adc

What my question is now, if we look at the output, than we see that mostly, the memory is aligned every 4 bytes but sometimes we see a bigger step like from 0x100100a7c to 0x100100a90 .

这是否正常? 如何防止这种情况? 为什么如此? 是否有可能强迫c把我的记忆作为固定线? (一) 不是原住民的english,但不知道如何说得更好)

仅供参考:-

感谢!

P.S.在三个记忆区中每个区一度或一度必须删除[] 整个阵列? EDIT:

我删除了现在这样的记忆,它非常好:

cout << "Free Memory" << endl;

for (int i = 0; i < m_sx; ++i) {
    for (int j = 0; j < m_sy; ++j) {
        delete [] m_array[i][j];
        //delete [] (*(*(m_array)+j)+k);
    }
    delete [] m_array[i];
}

delete [] m_array, m_array = NULL;
最佳回答

问题不是,你的记忆与......C++规格要求打电话new<>/code>和new[>的要求一致,即:它使一个点点重新点到对平台和所请求物体规模适当一致的相邻记忆。

您的问题是,你没有为阵列分配全方位缓冲,而是用多条电话(new[],而是用多个电话(new[]。 因此,每打<条码>新的电话将回馈一致和毗连的记忆,但要求<条码>新[<>/代码>的多条电话并不要求回馈本身同时分配的缓冲器。 例如,每打<代码>new[] 回归与记忆一致,但正如你指出的那样,在每一记忆阵列的开端可以有“gaps”,new 回归。 这些“选择”的原因可能具有多种原因,而且确实取决于基本职业顾问如何为你的方案分配记忆。

如果你不想在每一阵列中有任何“变式”,那么,你将需要分配整个缓冲地带,只打<代码>new。

最后,为了回答你关于<代码>delete[]的问题,是,由于你没有用一个电话把整个缓冲器分配给<代码>new[],你不能用一个电话删除你的阵列。 每一次电话<代码>new[],必须配对delete[],因为这些是单独的记忆分配。

问题回答

是的,这是正常的。 记忆为rot,btw., 它只是contiguous,因为随后打电话到new并不能提供这一保证。 是的,你可以在一个单一的、毗连的缓冲中分配整个3个阵列:

int *A = new int[size_x * size_y * size_z];

或更安全

std::vector<int> A(size_x * size_y * size_z);

后加指数

int element = A[i * size_z * size_y + j * size_z + k]

加入<代码>(i,j,k)。

事实上,这非常有用,因为它使你具有多面阵列,几乎没有间接费用,保留了>,并且防止间接。 此外,对这一分配办法的错误处理更为简单,这样你就会减少记忆泄露的风险。 任何良好的矩阵图书馆都将以这种方式实施。 C++, 包括Boost.MultiArray

关于营业地点:是的,您在本计划中需要多次电话delete[]

在此,在毗连的记忆空间中分配3D系列尺寸的N1×N2×N3,同时允许使用[i][j][k]辛奈。 阵列是动态的,但持续,因此,它具有巨大的附加作用,超越了病媒的配对;以及新的[]电话的方法与通道。

template <class T> T ***Create3D(int N1, int N2, int N3)
{
    T *** array = new T ** [N1];

    array[0] = new T * [N1*N2];

    array[0][0] = new T [N1*N2*N3];

    int i,j,k;

    for( i = 0; i < N1; i++) {

        if (i < N1 -1 ) {

            array[0][(i+1)*N2] = &(array[0][0][(i+1)*N3*N2]);

            array[i+1] = &(array[0][(i+1)*N2]);

        }

        for( j = 0; j < N2; j++) {     
            if (j > 0) array[i][j] = array[i][j-1] + N3;
        }

    }

    cout << endl;
    return array;
};

template <class T> void Delete3D(T ***array) {
    delete[] array[0][0]; 
    delete[] array[0];
    delete[] array;
};

以后,你执行例行公事......

int *** array3d;
int N1=4, N2=3, N3=2;

int elementNumber = 0;

array3d = Create3D<int>(N1,N2,N3);

cout << "{" << endl;
for (i=0; i<N1; i++) {
    cout << "{";
    for (j=0; j<N2; j++) {
        cout << "{";
        for (k=0; k<N3; k++) {
            array3d[i][j][k] = elementNumber++;
            cout << setw(4) << array3d[i][j][k] << " ";
        }
        cout << "}";
    }
    cout << "}";
    cout << endl ;
}
cout << "}" << endl;

Delete3D(array3d);

产出:

{
{{   0    1 }{   2    3 }{   4    5 }}
{{   6    7 }{   8    9 }{  10   11 }}
{{  12   13 }{  14   15 }{  16   17 }}
{{  18   19 }{  20   21 }{  22   23 }}
}

Since this is tagged C, here is also a C answer. Since C99 multidimensional arrays can be handled quite efficiently, even if the sizes are dynamic:

double c[size_x][size_y][size_z];

这把矩阵相加。 矩阵要素通过<代码>c[i][j][k]获取,汇编者为您编制所有计算索引。 如果你担心这可能会导致SO,那么你可以轻易地把<条码>小孔寄给:

double (*c)[size_y][size_z] = malloc(sizeof(double[size_x][size_y][size_z]));

Yes this is normal. You allocate data row by row; The only thing you can be sure is that data will be contiguous on each row.





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签