2

私のchar ** array2;の何が問題になっていますか。配列?

以下のコードは、malloc がメイン関数にある場合に正しく機能します。しかし、malloc が外部関数にある場合 ...これは機能しません。

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;

}
4

3 に答える 3

2

このリンクをチェックしてください。関数変数が C でどのように渡されるかを理解する必要があります。変数は C で値によって渡されます

このコードを試してください:

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 .

  • このメソッドでは、変数の値が渡されます。フォーマルに加えられた変更は、実際のパラメーターには影響しません。
  • 両方の変数に対して異なるメモリ位置が作成されます。
  • ここでは、元の変数に影響を与えない一時変数が関数スタックに作成されます。

array2これは、変数が関数で変更されない理由を説明しています。C の変数 (ポインターであるかどうかは問題ではありません) は、常に値によって渡されます。

それが役に立てば幸い!

于 2012-07-29T07:35:24.197 に答える
1

変化する

char ** array2; 

char * array2;  

変化する

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

function(&var1 , array1, &array2); 

あなたは大丈夫です。

あなたの問題は、関数の値としてarray2(ポインターではありますが)を渡すことでした。
これは、関数の終了後は変更が「表示」されないことを意味します。

于 2012-07-29T07:42:32.537 に答える
0

関数を呼び出す前に、次のものがあります。

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

したがって、あなたarray1array2両方がスタックに存在します。array2には値がありません。それは何も指していません。

関数を呼び出してみましょう。

関数には次のような呼び出し状態があります

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

あなたarray2が初期化されていないため、期待されています。

しかし、関数内でarray2が配置されている場所を見てください。

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

この値を以前の と比較します&array2array22 つの状況でメモリの異なる領域に配置されていることがわかります。この図は、何が起こるかを理解するのに役立ちます:

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

function's stack

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

つまり、関数に何かを渡すと、独自のスタックにある元のコピーが取得されることを理解していると思います。

初期化されていないポインターでは何もできません。呼び出し元のスタックにあるポインターを本当に変更したい場合は、ポインターを元のポインターに渡す必要があります。

まあ言ってみれば、

int * p; /* now it means */ 

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

のスタックfoo(&p)で thenのような関数を呼び出す場合:foo

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

これで、元のストレージへのポインタができました。だから私たちはそれで何でもできます。

通常の変数ポインターと同様に、同様の規則に従うことを理解することは非常に重要です。

「通常の」変数の参照を、その変数へのポインターとともに渡すことができます。しかし、ポインター自体への参照を渡したい場合は、別のレベルの間接化を行う必要があります。

ポインターを返すと、同様の効果を得ることができます。ポインターをローカルで初期化して、呼び出し元に返すことができます。

于 2012-07-29T09:01:58.037 に答える