Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between these two methods of memory allocation?

Tags:

c

pointers

The following are memory allocation method for a p[10][10] array.

//First
char** p;
int i;
p=(char**)malloc(10*sizeof(char*));
for(i=0;i<10;i++)
    p[i]=(char*)malloc(10*sizeof(char));

//Second
char** p;
int i;
p=(char**)malloc(10*sizeof(char*));
*p=(char*)malloc(100*sizeof(char));
for(i=1;i<10;i++)
    p[i]=p[0]+10*i;

What is the difference between the two?

like image 667
prasanth unnam Avatar asked Dec 04 '22 02:12

prasanth unnam


2 Answers

Neither of these are C++. The first allocates an array of 10 char*, and then assigns each of those to a separate dynamically allocated array of 10 char. Each array of 10 is independent, so you have no guarantee for what the difference is between p[0][9] and p[1][0]:

  p
+------+
| p[0] |  --> [][][][][][][][][][]
+------+
| p[1] |  --> [][][][][][][][][][]
+------+
|      |  --> [][][][][][][][][][]
+------+
 ...  
+------+
| p[9] |  --> [][][][][][][][][][]
+------+

In the second case, you have one contiguous array of 100 char, and your 10 char* each point to different segments in there:

   0  1  2      10     20
  +--+--+--+   +--+   +--+
  |  |  |  |...|  |...|  |...    <== dynamically allocated array of 100 char
  +--+--+--+   +--+   +--+
    |         /       /
    \        /       /
  +------+------+------+
p | p[0] | p[1] | p[2] |...      <== dynamically allocated array of 10 char*
  +------+------+------+

Here you do have a guarantee that the next char after p[0][9] is p[1][0].

Though neither of these are really arrays. To do that, you'd want:

char p[10][10]; 

which would give the equivalent behavior of that second block - minus all the extra overhead of the 10 char*s and the dynamic memory allocation. In C++, we'd prefer to write that one as:

std::array<std::array<char, 10>, 10> p;
like image 114
Barry Avatar answered May 25 '23 16:05

Barry


You are dynamically allocating arrays in your snippets. The difference is that first snippet allocates memory for each of 10 char pointers in a zig-zag (depending on the availability of memory space) manner. Second snippet allocates contiguous memory for each of 10 char pointers.

See the pic to get it more clear

int **array1 = malloc(nrows * sizeof(int *));
    for(i = 0; i < nrows; i++)
        array1[i] = malloc(ncolumns * sizeof(int));    

enter image description here

int **array2 = malloc(nrows * sizeof(int *));
    array2[0] = malloc(nrows * ncolumns * sizeof(int));
    for(i = 1; i < nrows; i++)
        array2[i] = array2[0] + i * ncolumns; 

enter image description here

Further reading: How can I dynamically allocate a multidimensional array?.

like image 40
haccks Avatar answered May 25 '23 17:05

haccks