0

When we create an array, for example int arr[2][4];, its size becomes 2x4x4 = 32, but if we do this dynamically, its size becomes more then 32.

For instance, I wrote this code:

#include <iostream>
#include <stdlib.h>

using namespace std;
// arr[4][2]
int main(){
    int **arr;
    arr = (int**)malloc(4*sizeof(int*));
    
    int i;
    for(i=0;i<4;i++){
        *(arr+i) = (int*)malloc(2*sizeof(int));
    }
    arr[3][1] = 4;
    cout << arr[3][1];


    return 0;
}

There are 8 + 4x8 + 4x2x4 = 72 bytes allocated. That's why I thought the program is doing different and I wonder how it does this.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    Because, in a true array, there are no lookups for each row: all the elements are contiguous. – Weather Vane May 26 '21 at 23:03
  • 2
    In C++ you should use `new`, not `malloc()`. – Barmar May 26 '21 at 23:05
  • What do you mean _"not dynamic"_? Your code does _dynamic allocation_. A static array definition just reserves a contogous array of data elements at it's scope (local, or global), why would you expact these sizes to be equal ? – πάντα ῥεῖ May 26 '21 at 23:07
  • 1
    @πάνταῥεῖ I think the title means he's wondering about `int arr[2][4];` – Barmar May 26 '21 at 23:09
  • @WeatherVane Actually, when we create an array like `int arr[4][2]` we can use `*(arr+1)` so, that makes some lookups exist. – Ahmet Talha Yıldırım May 26 '21 at 23:40
  • 1
    Yes, but because the elements are contiguous, the compiler needs only the base address to compute the location of any element. But when you allocated the array of pointers, the allocation for each row has no proximity to the other rows, and so a separate pointer was used for each row. – Weather Vane May 26 '21 at 23:42
  • Creating an array `int arr[4][2]` does not create an array of four pointers that each point at an array of two `int`. It simply allocates space for eight `int`s (or of four contiguous arrays, each of which is an array of two `int`). Since the compiler knows the type, it maps a pair of indices to a correct element. Your usage of `malloc` creates an array of four pointers, then causes each of those pointers to point at a (dynamically allocated) array of two `int`. So your usage of `malloc()` does not create a 2D array. – Peter May 27 '21 at 03:08

2 Answers2

3

What you've done here isn't exactly a 2D array although it behaves like one syntactically. What you instead have is an array of pointers, and each of those pointers points to an array of int.

If you want to allocate an actually 2D array you would do so like this:

int (*arr)[2] = malloc(4 * sizeof *arr);
dbush
  • 205,898
  • 23
  • 218
  • 273
1

int arr[4][2] allocates a single block of memory, with indexes laid out like this:

0,0 0,1
1,0 1,1
2,0 2,1
3,0 3,1

Each element is 4 bytes to hold an int.

In your dynamic allocation method, you have 8 bytes for the arr variable itself. Then the first malloc() allocates an array like this:

ptr0 ptr1 ptr2 ptr3

This is 4x8 bytes.

Then you call malloc(2 * sizeof(int)) 4 times, which allocates 4x2x4 bytes.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • The first thing you said "int arr[4][2] allocates a single block of memory" is okay but then how arr behaves like a pointer of pointer. If it behaves like a pointer of pointer, I should be able to do it dynamically. – Ahmet Talha Yıldırım May 26 '21 at 23:28
  • 1
    If an array is used in a context where a pointer is needed, its value decays to a pointer to its first element. – Barmar May 26 '21 at 23:29
  • So if you write `arr+1`, it acts like an `int[2]*` pointer. Or if you pass it as a function argument. – Barmar May 26 '21 at 23:30
  • 1
    @AhmetTalhaYıldırım: You may want to read this: [What is array to pointer decay?](https://stackoverflow.com/q/1461432/12149471) – Andreas Wenzel May 26 '21 at 23:31