2017-10-27 4 views
0

を文字列を割り当てることができていますように(私は信じているスタック上に?):strncpyをワンセグ障害が、私は定義された配列charへのグローバルポインタ持って手動で

char *history[BUFFER_SIZE]; 

そして、私は単純にしたいメソッド内:

strncpy(history[0], str, length); 

となります。それ以来私に意味をなさない:

history[0] = "a string" 

はsegフォールトです。

私の質問:私はこのようなchar型の配列の配列を定義しておりますので

  1. 、私は正しい、malloc関数または初期化の任意の並べ替えを実行する必要はありませんか?
  2. なぜエラーが発生していますか?
+0

'history [0] =" a string "は*文字列リテラル*へのポインタです。 'strncpy'または他の方法でそれに書き込むことは、いいえいいえです。しかし、疑問は不明です。 'history [0 ...]'にメモリを割り当ててデータをコピーすることができない場合、 'strncpy(history [0]、str、length);'は失敗します。 –

答えて

3

char *history[BUFFER_SIZE];は、char*の配列で、どこも指していません。それらのポインタにstrncpyをしようとすると、未定義のビヘイビアが呼び出されます(これはどこにも指していないため)、これはセグメンテーションとして表示されています。

ときhistory[0] = "a string"これはhistory[0]char*を割り当て、そのhistory[0]もはやポインタがどこにも、それは"a string"を指していないし。 "a string"はプログラム内の他の場所に格納されている文字列リテラルです。ほとんどの場合、読み取り専用セクションです。 history[0]は実際にはデータ"a string"を含んでおらず、単に"a string"のアドレスを含んでいます。

私はこのようなchar型の配列の配列を定義しておりますので、私は は正しい、malloc関数または初期化の任意の並べ替えを実行する必要はありませんか?

あなたのやりたいことによって異なります。 history[0] = "a string"を実行するのはまったく問題ありません。文字列リテラルなので、その文字列を変更しようとすると未定義の動作であることがわかります。文字列リテラルを、自由にコピーを変更できるメモリセクションにコピーする場合は、mallocまたはそれに類するメモリを割り当てる必要があります。しかし、char *history[BUFFER_SIZE];は "char配列の配列"を定義していないので、charポインタの配列を定義しています。

+0

ああ、私は今理解していると思う。したがって、mallocなしで配列を定義する(静的に意味がわからない)場合は、次のようにします。 char history [BUFFER_SIZE] [str_len];以前に行ったようにhistory [0] = "..."を割り当てますか?そういうわけで、私はあらかじめ長さを割り当てています。今すぐ動作しているようです。 – Zhinkk

+1

@Zhinkkはい、 'malloc'を使いたくない場合、コンパイラはコンパイル時にどれくらいのスペースを必要としているかを知る必要があります。もしあなたが 'char history [BUFFER_SIZE] [MAX_WORD_LENGTH];'のようなことをするならば、あなたの配列に 'MAX_WORD_LENGTH-1'文字まで' BUFFER_SIZE'ワードまで 'strcpy'することができます。文字列には 'NUL'ターミネータが必要です)。 – yano

+1

@Zhinkkは、 "文字列"が 'str_len'より長くない限り、以前と同じように' strcpy'を使用します。 '= '演算子は文字列をコピーしません。 – yano

1

historyはポインタの配列です。文字列全体を32bまたは64bのサイズにコピーすることはできません。

実際には、ポインタがスタックまたはヒープにあるかどうかにかかわらず、ポインタに関連付けられるメモリを割り当てる必要があります。 2番目の例では、ポインタスタックにアドレスを割り当てる前に文字列に割り当てられたメモリを割り当てています。

関連する問題