2016-08-03 14 views
-1

私はこれが基本的だと知っていますが、私はこれを論理的に考えており、これは得られません。 なぜ配列に渡された配列がnullですか?

char *me[] = {0}; 
getHardwareEEprom(me); 
printf("**%s\n", me[0]); // null 

void EEprom::getHardwareEEprom(char *eeprom[]) 
{ 
    char *EEPROM[]={"A4", "B3", "C=AB", "if(C7)", "(C)", NULL}; 
    eeprom = EEPROM; // set the address for the data array 
} 
  1. me

    は、いくつかの場所を指すポインタである
  2. そのことが
  3. meが配列のために今のアドレスを保持しているメモリ内のいくつかの配列のアドレスを取得し、この関数に渡さEEPROM
  4. 最初の文字を表示するnull

私は多くを読んで、私はちょうどこのことを取得していないようです。

+4

読む[尋ねる]とありがとう – xenteros

答えて

7

特に特別なことはありません。

機能パラメータeepromに割り当てられているものを変更しています。それだけです。その割り当ては、有効期間はEEPROMです。

しかし、その変更は呼び出し元に反映されません(C++は値渡し言語です)。したがって、発信者のmeはそのままです。

機能パラメータeepromが完全に別の問題であったのは、参照です。

+0

ありがとう。あなたはそれをどのように参考にしますか? – Curnelious

+2

関数のパラメータリストで、これらの物のいずれかを '&'で使用します。 – Bathsheba

+3

「EEPROM」が割り当て解除されていなくても、この割り当ては無効です。 'eeprom'のあなたのグローバルコピーは、新しいアドレス値を取得しません。 – naccyde

2

char *EEPROM[]={"A4", "B3", "C=AB", "if(C7)", "(C)", NULL};には、自動的に記憶域が割り当てられます。

関数getHardwareEEpromが終了して呼び出し元に戻るまで、それは存続します。

また、char *eeprom[]にはローカルスコープがあるため、関数内の関数への変更は渡されたポインタに反映されません。

終わりには、Cスタイルのソリューションは、あなたは、関数が返すスコープの外に出るローカル変数、EEPROMを、

#include<stdio.h> 

void getHardwareEEprom(char ***eeprom) 
{ 
    static char *EEPROM[]={"A4", "B3", "C=AB", "if(C7)", "(C)", NULL}; 
    *eeprom = EEPROM; // set the address for the data array 
} 

int main(void) 
{ 
    size_t i=0; 
    char **me = {0}; 
    getHardwareEEprom(&me); 
    while(me[i] != NULL) 
    { 
     printf("%s\n", me[i]); 

     i++; 
    } 
} 
+0

最初の行から '*'削除してください。それはそれを明らかにする。だから、同じ機能を得る方法はありますか? – Curnelious

+0

まあ、たくさん。最後に[tag:C++]が渡されたので、渡されたポインタの 'new'メンバーか、単純に' EEPROM'配列を 'static'または' global'にすることができます – LPs

+0

私はこれが実際にUBではないと思います。私が間違っているなら、もう一度チェックし、私の答えをdownvoteしてください。 – Bathsheba

2

代入していることができますので、あなたがprintfを呼び出すときには有効ではありません。

1

引数は、ステートメント

eeprom = EEPROM; 

は、呼び出し元の関数では効果がありませんC.に値によって渡されます。

1

まず、これはCではなくC++です(Cにはクラスがありません、チェックEEprom::)。

また、変数のスコープに注意してください。ここではchar *EEPROM[]={"A4", "B3", "C=AB", "if(C7)", "(C)", NULL};が定義されており、メモリは関数内に割り当てられているため、関数が返るとメモリは割り当て解除されます。

もう1つの問題は、パラメータを返さずにアドレスを設定できないことです。引数を参照すると、関数はポインタアドレスのコピーを取得します。次に、あなたの例では、関数のローカルコピーeepromは、そのアドレスをEEPROMのアドレスに変更します。

char **foo(void) 
{ 
    char **EEPROM = NULL; 
    // Here you should allocate your memory with malloc and fill the array with your data 

    return EEPROM; 
} 

char **bar = foo(); 

この方法では、あなたがあなたの2つの問題を解決する:しかし、世界的なコピーこれを回避するために、新しいアドレスを取ることはありません(関数を呼び出すために使用されるもの)は、あなたの関数は、適切なアドレスを返すことができるあなたが行います割り当てられていないメモリへのポインタを使用せず、関数外のデータへの有効なポインタを取得します。

1

getHardwareEEprom(me);が呼び出されたときは、meというアドレスを関数に渡しています。そのアドレスには、関数内でが指しています。

ただし、関数内でeeprom = EEPROM;を実行するとすぐに接続が残っていません。そして、eepromは完全に他の場所を指しています。つまり、EEPROMの配列のアドレスを指しています。したがって、eeprommeはもう関係がありません。

あなたが期待しているように、あなたがしなければならないmeの内容を変更するには:

eeprom[0] = "test"; // OR 
*eeprom = "test"; 
関連する問題