user1560613
user1560613

Reputation: 31

c malloc for two dimensional char array by passing this array to function

What is wrong with my char ** array2; array?

Code below is working correctly when malloc is in main function. But when malloc is in external function ...this doesn't work.

void function(int *var1 ,int array1[][3], char** array2);

main(){
 int var1 = 0
 int array1[10][3];
 char ** array2;

 function(&var1 , array1, array2); //Something wrong in here???

 printf("Value of var1: %d\n", var1 );                 /*Display 5 - OK*/
 printf("Value of array1[0][0]: %d\n", array1[0][0] ); /*Display 6 - OK */
 printf("Value of array2[0]: %s\n", array2[0]);        /*Error - Function stops here */
return;
}



void function(int *var1 ,int array1[][3], char** array2)
{
  int i = 0;
  array2= malloc(10 * sizeof(char *));
  for(i = 0; i<10; i++)
  {
    array2[i] =  malloc(10 * sizeof(char *));
    strcpy(array2[i], "SomeText");
  }

  *var1 = 5;

  array1[0][0] = 6; 

  printf("Value of var1: %d\n", var1 );                 /*Display 5 - OK*/
  printf("Value of array1[0][0]: %d\n", array1[0][0] ); /*Display 6 - OK */
  printf("Value of array2[0]: %s\n", array2[0]);        /*Display "SomeText - OK*/

 return;

}

Upvotes: 2

Views: 1254

Answers (3)

Aftnix
Aftnix

Reputation: 4589

Before calling your function you have these :

(gdb) p/x &array1
$7 = 0x7fffffffe080
(gdb) p/x &array2
$8 = 0x7fffffffe108
(gdb) p/x array2
$9 = 0x0

So your array1 and array2 both resides in stack. array2 has no value. Its not pointing to anything.

Lets call the function now,

function has its calling state like

function (var1=0x7fffffffe104, array1=0x7fffffffe080, array2=0x0)

Its expected because your array2 is not initialized.

But inside the function look at where array2 is located,

(gdb) p/x &array2
$10 = 0x7fffffffe038
(gdb) p/x &array1
$11 = 0x7fffffffe040

Compare this value with the earlier &array2. You see array2 is located in different areas of memory in two situations. This diagram will help you to understand what happens :

main()'s stack : 
+---------------+
|0x7fffffffe080 |
+---------------+                  
array1
+---------------+
|0x7fffffffe108 |
+---------------+
array2

function's stack

+---------------+
|0x7fffffffe040 |
+---------------+                  
array1
+---------------+
|0x7fffffffe038 |
+---------------+ 
array2

So i guess you have understood that when you pass anything to a function, what it gets its a copy of the original located in its own stack.

You can't do anything with a uninitialized pointer. If you really want to change a pointer located at caller's stack, you need to pass a pointer to the original pointer.

lets say,

int * p; /* now it means */ 

p:
+---------------+------------+
| 0xABCD        |  0x00      |
+---------------+------------+

if i call a function like foo(&p) then in foo's stack :

+---------------+------------+
| 0xEFGH        |  0xABCD    |
+---------------+------------+

Now we have a pointer to the original storage. So we can do anything with it.

Its very important to understand that like ordinary variables pointers are also follow similar rules.

You can pass a "ordinary" variable's reference with a pointer to it. But if you want to pass a reference to the pointer itself you have to go another level of indirection.

You can achieve the similar effect if you return a pointer. you can locally initialize a pointer the return it to the caller.

Upvotes: 0

Cacho Santa
Cacho Santa

Reputation: 6914

Check out this link. You need to understand how are the function variables pass in C. The variables are passed by value in C.

Try this code:

void function(int *var1 ,int array1[][3], char*** array2);

int main(int argc, char*argv[]){
     int var1 = 0;
     int array1[10][3];
     char **array2;

     function(&var1 , array1, &array2); //Something wrong in here???

     printf("Value of var1: %d\n", var1 );                 /*Display 5 - OK*/
     printf("Value of array1[0][0]: %d\n", array1[0][0] ); /*Display 6 - OK */
     printf("Value of array2[0]: %s\n", array2[0]);        /*Error - Function stops here */
    return;
}



void function(int *var1 ,int array1[][3], char*** array2)
{
  int i = 0;
  (*array2)= malloc(10 * sizeof(char *));
  for(i = 0; i<10; i++)
  {
    (*array2)[i] =  malloc(10 * sizeof(char *));
    strcpy((*array2)[i], "SomeText");
  }

  *var1 = 5;

  array1[0][0] = 6;

  printf("Value of var1: %d\n", *var1 );                 /*Display 5 - OK*/
  printf("Value of array1[0][0]: %d\n", array1[0][0] ); /*Display 6 - OK */
  printf("Value of array2[0]: %s\n", (*array2)[0]);        /*Display "SomeText - OK*/

 return;

}

Pass By Value:(in C) from this link.

  • In this method value of the variable is passed. Changes made to formal will not affect the actual parameters.
  • Different memory locations will be created for both variables.
  • Here there will be temporary variable created in the function stack which does not affect the original variable.

That explains why your variable array2 does not change in your function. The variables in C - it does not matter if it is a pointer - are always passed by value.

Hope it helps!

Upvotes: 2

Roee Gavirel
Roee Gavirel

Reputation: 19443

change

char ** array2; 

with

char * array2;  

change

function(&var1 , array1, array2); //Something wrong in here???  

with

function(&var1 , array1, &array2); 

and you'll be fine.

you problem was the you pass array2 (although pointer) as a value in the function.
which mean that any change you make to it won't be "seen" after the function ends.

Upvotes: 1

Related Questions