This question has already been answered:

I wanted to sort the matrix, working with it as with a one-dimensional array, that is, moving directly through memory. If you make a static array int a[2][2] , then on request std::cout << *(*a+3); I get the same a[1][1] that I need. But as soon as I made a dynamic array

 int** b = new int*[2]; for(int i = 0; i < 2; i++) { b[i] = new int[2]; } 

then with the same call std::cout << *(*b+3); and for any value, outside the 1st row (for a given matrix, with 1 and 2 outputs the value, and with 3 and 4 outputs 0) it displays 0. Rummaged in this (if I'm not mistaken, then std::cout << *(b + i); should output the address of the 0th element of the i-th line) it turned out that if you create an array on the n-th number of lines and
from 1 to 6 elements - 32 bytes are allocated to each line
from 7 to 10 elements - 48 bytes per line
from 11 to 14 - 64 bytes each
from 15 to 18 - 80 bytes
and so on
Please explain how it works.

Reported as a duplicate by the participants pavel , αλεχολυτ , aleksandr barakin , Cerbo , cheops 2 Oct '16 at 18:24 .

A similar question was asked earlier and an answer has already been received. If the answers provided are not exhaustive, please ask a new question .

  • What you call a dynamic array is not; you simply allocate memory for the array either on the stack or on the heap. It is customary to call dynamic arrays that can change their size while the program is running; for C ++, this will be std :: vector. By the way this is a common mistake of newbies, and who only teaches them this? - Cerbo

3 answers 3

It’s not very clear why you should bother yourself with address arithmetic, if we are talking about C ++. But if you really want to ...

Either you need to allocate a continuous piece of memory with the size of NxM, and access the element [n][m] as k *(data + m*N + n) .

Either way:

 #include <iostream> const size_t N = 2; const size_t M = 3; int main() { // здесь мы выделили один непрерывный блок указателей: int **data = new int *[N]; for( size_t i = 0; i < N; i++ ) { // а здесь мы выделяем другие непрерывные блоки, // уже для переменных. адреса которых записываем в // элементы массива, полученного на предыдущем // этапе. ну и заполним их чем-нибудь для контроля: data[i] = new int[M]; for( size_t j = 0; j < M; j++ ) { *( data[i] + j ) = i * M + j; // оно же: // data[i][j] = i * M + j; } } // проверим что получилось: for( size_t i = 0; i < N; i++ ) { for( size_t j = 0; j < M; j++ ) { std::cout << *( data[i] + j ) << " "; } std::cout << "\n"; } return 0; } 

    The declarations int a[2][2] and int **a not equivalent and have fundamentally different meanings.

    The first is a 2x2 array created on the stack, the memory for which is a continuous chunk of memory

    The second is a pointer to a pointer. In other words, when you do an int **a = new *int[2] , memory is allocated for two pointers. Because operator new allocates memory in a heap, it is allocated more or less arbitrarily. It turns out that you have a memory block with an array of pointers to some other memory area.

    • This is understandable, but why memory for a line is not allocated to i*sizeof(T) , where i is the number of elements in a line, but in blocks? - sm4ll_3gg 9:01 pm
    • What line? I do not really understand what bothers you. - user1056837
    • one
      @ sm4ll_3gg, in int** b = new int*[2]; you made (somewhere in memory) an array of 2 pointers, and in b[i] = new int[2]; make another array of 2 int and memorize its address in the 1st array of pointers. For a 2x2 matrix, you allocate memory 3 times in total (mb randomly). To access the i, j-th element, just write b[i][j] , for example, to display the last cout << b[1][1] << ... - avp
    • Probably talking about the size of the first array. Here the matter is that there is no difference in what the pointer is - its size depends on the 32/64 bit platform. - user1056837

    You can create a multidimensional array in a heap like this:
    int(*b)[2] = new int[2][2];

    Or if C ++ 11 is available, it can be simplified to:
    auto b = new int[2][2];

    Refer to items:

     b[1][1] = 42; int x = b[1][1]; int y = *(*b + 3); 

    Delete:
    delete[] b;

    • error: conflicting declaration 'int (* b)[2]' int (*b)[2] = new int[2][2]; - sm4ll_3gg
    • sure that ad b is unique? - Slava Zhuyko Sep. 6:49 pm
    • example: ideone.com/tNSpcn - Slava Zhuyko