2012-04-23 9 views
0

私はCでまだ新しいですし、2dのchar配列を空にしようとしています。ここで宣言は次のとおりです。これは私を与えるように思われるので、任意の助けがそうCで2d char配列を空にするには?

を高く評価している

void make_empty(char **arg_array) 
{ 
    int i; 
    for(i = 0; i <= BUFSIZ; i++) 
    { 
     arg_array[i][0] = '\0'; 
    } 
    return; 
} 

私は右のそれをやっているセグメンテーション違反:私はそれを空にしようのはここ

char arg_array = (char**)calloc(strlen(buf), sizeof (char**)); 
for(i = 0; i<(strlen(buf)); i++) 
{ 
    arg_array[i] = (char*) calloc (strlen(buf), sizeof(char*)); 
} 

です配列にデータを追加してから印刷しようとするとどうなりますか?

空で空にするだけです - 詳細はどうやって説明できますか? lol

+0

各サブアレイの最初の要素を変更するだけです...あなたのコンテキストでは "空"とは何ですか? – UmNyobe

+0

jのような別の変数がある場合は、0〜columnSize - 1の内部forループを作成します。BUFSIZEをrowSize - 1に変更します。 – mert

+0

char *をnullプラグの最初の文字にすることで空にできます。私はあなたが2次元配列にこれを適用できると仮定していますが、この関数を使って "空"にして再利用しようとすると、seg faultsが発生します。 – beyondavatars

答えて

1

空にする必要はありません。多くの場合C言語では、メモリ割り当てはmallocで行われ、呼び出し側が所有しているメモリブロックが返されます。 callocが呼び出され、メモリのブロックが返されると、メモリは0に初期化されることが保証されます。これは、すべての目的と目的のために既に '空'であることを意味します。

また、あなたのコードが意図していることをしているかどうかはわかりません。現時点での説明を教えてください:

char arg_array = (char**)calloc(strlen(buf), sizeof (char**)); 

この行は間違っています。 Cでは、callocから返されたポインタは、void *なのでキャストする必要はありません。他のポインタ型に暗黙的にキャストされています。この場合、それは意味をなさないcharタイプに格納しています。あなたがこれを行う場合:

char ** arg_array = calloc(strlen(buf), sizeof (char**)); 

をそれからそれはstrlen(buf)長さのポインタの配列を割り当てます。したがって、buf"hello"の場合、5つのポインタを格納できる配列が割り当てられました。

for(i = 0; i<(strlen(buf)); i++) 
{ 
    arg_array[i] = calloc (strlen(buf), sizeof(char*)); 
} 

また、冗長キャストを削除しました。これは、前に割り当てられた配列に値を設定します。配列の各インデックスはcharの文字列strlen(buf) * sizeof(char *)を指すようになりました。 これはおそらくあなたが望むものではありません。


あなたの質問は今私には明らかです。文字列を入力した後に文字列を削除したいようです。あなたはそれを二つの方法行うことができます。

  • どちらかfreeポインタのそれぞれをして
をあなたは
  • 前に行ったように、後に多くのスペースを割り当てるか、null文字までの文字列のそれぞれの最初の文字を設定しますヌル文字に、各文字列の最初の文字を設定するには

    for(i = 0; i<(strlen(buf)); i++) 
    { 
        free(arg_array[i]); 
    } 
    

    :ポインタを解放するために

    for(i = 0; i<(strlen(buf)); i++) 
    { 
        arg_array[i][0] = '\0'; 
    } 
    

    これは元々のものと同じコードで、うまくいくはずです。


    証拠として、次のコードはエラーなしで実行されます:あなたのコードは、セグメンテーションフォルトれ

    #include <stdlib.h> 
    #include <stdio.h> 
    #include <string.h> 
    
    int main(void) 
    { 
        char * buf  = "hello"; 
        char ** arg_array = calloc(strlen(buf), sizeof (char**)); 
        unsigned int i; 
    
    
        for(i = 0; i < strlen(buf); i++) { 
         arg_array[i] = calloc(strlen(buf), 
           sizeof(char *)); 
        } 
    
        for(i = 0; i < strlen(buf); i++) { 
         arg_array[i][0] = '\0'; 
        } 
    
        for(i = 0; i < strlen(buf); i++) { 
         free(arg_array[i]); 
        } 
    
    
        free(arg_array); 
        return EXIT_SUCCESS; 
    } 
    

    場合は、問題がどこか別の場所から来ています。変数arg_arrayを上書きしましたか? BUFSIZEstrlen(buf)と等しいですか?行は、あなたの配列のCOLSのrowsとcols数の数である

    void make_empty(char **arg_array, int rows, int cols) 
        { 
        int i,j; 
        for(i = 0; i <rows; i++) 
        { 
         for(j=0; j<cols;j++) 
         { 
          arg_array[i][j] = '\0'; 
         } 
        } 
        return; 
        } 
    

  • +0

    私は言葉でそれを記入し、私は再びそれを空にする必要があります。私は質問にこれを述べたと信じています。だからこの答えは、私が探していたものではなかったでしょう。 – beyondavatars

    +0

    'sizeof(char *)'と 'sizeof(char *)'ではなく、 'sizeof(char *)'と 'sizeof(char)'(これは不要なので1)をループに対して使用しないでください。 – twain249

    +0

    @ twain249:はい、私はこれを修正しませんでした。 OPがおそらく 'sizeof(char *)'を意味するところで 'sizeof(char **)'が使われます。しかし、両方の値が等しい。 'sizeof(char)'は私の答えのどこにも使われていません。 –

    0

    はこれを試してみてください。

    P.S.この関数は、常に行うべきであるように配列全体をクリアします。私が前にコメントしたように、文字列の最初の文字として '\ 0'を入れても行全体はクリアされません。残りの部分はprintfのような関数では見えません。 http://cplusplus.com/reference/clibrary/cstdio/printf/

    +1

    'memset'ははるかに簡単な代替手段です。 –

    +0

    私は知っていますが、この例では、質問者が誤解したことを理解することがより簡単になると思います(下記のコメントを参照)。 – Wookie88