i have a quite weird question which probably has no practical use but the answers bothers me a lot. I tried to mess around today a little bit with arrays and how they are allocated in memory using this code: (Compiler Xcode 4 btw, 4 byte integer)
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;
When i enter now: 3, 2 and 4 i get the following output in the console:
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 .
Is this normal and how can i prevent this? Why is this? Is there a possibility to force c to align my memory as a constant line? (I'm not native english so sorry for that but i don't know how to say it better)
Its just for general understanding :-)
Thank u!
P.S. is it enough to use delete [] once btw or do i have to go through each of the 3 memory blocks and delete [] there the whole array? EDIT:
I delete memory now like this and it works pretty good:
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;
Yes, this is normal. The memory is aligned, btw., it's just not contiguous because subsequent calls to new
do not make this guarantee. And yes, you can allocate the entire 3-d array in a single, contiguous buffer:
int *A = new int[size_x * size_y * size_z];
or, safer
std::vector<int> A(size_x * size_y * size_z);
and then index it with
int element = A[i * size_z * size_y + j * size_z + k]
to get the element at (i,j,k)
.
This is, in fact, very useful, as it gives you multidimensional arrays with little overhead, preserving locality of reference and preventing indirection. Also, the error handling for this allocation scheme is much simpler so you run less of a risk of memory leaks. Any good matrix library will be implemented this way. For C++, that includes Boost.MultiArray.
As for deallocation: yes, you need multiple calls to delete[]
in your present scheme.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With