What is the difference between these two ways of allocating memory?

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

 //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?

+4
source share
3 answers

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

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

In the second case, you have one continuous array of 100 char , and your 10 char* each points to different segments:

  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 have the guarantee that the next char after p[0][9] will be p[1][0] .

Although none of them is an array. For this you need:

 char p[10][10]; 

which will give the equivalent behavior of this second block - minus all the additional overhead of 10 char* and the allocation of dynamic memory. In C ++, we would rather write this as:

 std::array<std::array<char, 10>, 10> p; 
+9
source

You dynamically allocate arrays in your fragments. The difference is that the first fragment allocates memory for each of the 10 char pointers in zig-zag (depending on memory availability). The second fragment allocates continuous memory for each of 10 char pointers.

Look at the pic to figure it out.

 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? .

+4
source

In this code snippet

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

memory is allocated for a one-dimensional array of 10 char * pointers:

 p=(char**)malloc(10*sizeof(char*)); 

Each pointer, in turn, is initialized with the allocated memory address for a one-dimensional array of 10 elements of type char :

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

In this fragment of the fragment

 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; 

first, memory is allocated for a one-dimensional array of 10 elements of type char * , as in the first code fragment.

 p=(char**)malloc(10*sizeof(char*)); 

However, then only the first element of the array is initialized with the address of the allocated memory for the bulk array of 100 elements of type char .

 *p=(char*)malloc(100*sizeof(char)); 

The above statement is equivalent

 p[0]=(char*)malloc(100*sizeof(char)); 

And then the other 9 pointers are initialized with integer expressions 10*i

 for(i=1;i<10;i++) p[i]=p[0]+10*i; 

Obviously, this does not make sense. The values ​​of these 9 elements are invalid because they are not pointers to objects. This is the purpose of these initializations is unclear.

Note that you can allocate memory for one two-dimensional array as follows:

 char ( *p )[10] = malloc( 100 * sizeof( char ) ); 

The advantage of this allocation is that you only need one call to the free function to free up all the allocated memory. And, in addition, this pointer can be used as an argument for a function that has a parameter in the form of two two-dimensional arrays.

for instance

 void func( char a[][10] ); 

You can call this function, for example

 func( p ); 

However, you cannot call a function if p is of type char ** , because this type is incompatible with the type of the parameter.

+3
source

All Articles