2

季節のご挨拶!多数の文字列を格納する配列として使用されている char** の内容を出力する関数があります。は次のように宣言されます。

char** commandArray = (char**)malloc(historySize);

ここで、historySize は 8 に設定されたグローバルな int です。配列には、循環キューのような形で、ユーザーが入力するコマンドが取り込まれます。バッファの内容を出力したい場所がいくつかあるので、関数を作成しました。理想的には、関数は commandArray への参照を受け取り、それをループして、その内容を出力します。ここで、ポインターと参照は私の得意分野ではないことを言わなければならないので、正しく行っているかどうかはよくわかりません。関数は次のようになります。

    /* prints the contents of the history buffer */
void printHistory(char*** historyBuff)
{
    /* a counter for the loop */
    int loopIdx = 0;

    for (loopIdx = 0; loopIdx < historySize; loopIdx++)
    {
        /* print the current history item */
        printf ("\nhistoryBuff[%i] = %s\n", loopIdx, *historyBuff[loopIdx]);
        fflush(stdout);
    }
}

次のように、char** を関数に渡します。

printHistory (&commandArray);

現状では、すべて正常にコンパイルされますが、プログラムが履歴を出力すると、関数がループのどこかでハングし、char** の内容が出力されません。SO、私の質問は次のとおりです。commandArray を適切に渡していますか、関数を正しく宣言していますか、関数内で正しい方法で逆参照していますか?

すべてのヘルプや提案を事前にありがとうございます!

-ベン

4

2 に答える 2

10
  1. コードをそのまま動作させるには、次のように逆参照する必要があります。

    (*historyBuff)[loopIdx]

    あなたが書いた方法は、Cの演算子の優先順位のために[]以前に発生しましたが、それはあなたが望むものではありません.*

  2. コマンド配列用により多くのスペースを割り当てる必要があります。現在、実際には を保持するhistorySize char*のに十分な大きさではありません:

    char** commandArray = (char**)malloc(historySize * sizeof(char*));
    
  3. この配列を「参照」で渡す必要はありません。次のように関数を宣言できます。

    void printHistory(char** historyBuff)
    

    そしてcommandArray直接渡します。char***関数内のどこかで実際の配列ポインターを変更する場合 (たとえば、reallocより多くのスペースを作成する必要がある場合)にのみ、a を渡す必要があります。

  4. ものだけを出力する関数の場合、もう少し進んで、ものを宣言することができますconst。これは、配列またはその中の文字列を変更しないという呼び出し元への「保証」です (C で何かを保証できる限り)。

    void printHistory(const char *const * historyBuff)
    
于 2009-12-28T16:39:37.817 に答える
1

1.

mallocポインターではなく、バイト数を割り当てます。が割り当てている文字ポインタの数である場合は、次のように変更する必要があります。historySize

char** commandArray = (char**)malloc(historySize);

に:

char** commandArray = malloc( historySize * sizeof(char*) );

2.

あなたはポインタprintHistory()を変更しません。commandArrayを渡す必要はありませんchar***。Achar**します。

于 2009-12-28T16:42:08.977 に答える