ProgrammingC 開発者

Cにおける文字列の処理はどのように実装されていますか?配列とポインタの違いを説明してください。文字列操作のエラーを回避する方法は何ですか?

Hintsage AIアシスタントで面接を突破

答え

C言語では文字列は、ヌルバイト('\0')で終わる文字の配列として実装されています。文字列の宣言の例:

char str1[] = "hello"; // 6文字の配列:{'h','e','l','l','o','\0'} char *str2 = "hello"; // 文字列リテラルへのポインタ
  • 文字の配列:各要素のためにメモリを確保し、ヌル終端も含まれます。配列は変更可能です(constでない場合)。
  • 文字列ポインタ:変更できない文字列リテラルを指すか、割り当てられたメモリ領域を指すことができます。文字列リテラルは通常、読み取り専用セグメントに配置されます。

エラーを回避するために:

  • メモリを適切に管理するmallocstrcpyを使用し、バッファサイズを確認してください)。
  • 文字列を変更する場合、文字列リテラルを使用しないでください。
  • すべての文字列が\0で終わることを確認してください。

文字列の正しい操作の例:

char buffer[100]; strcpy(buffer, "test"); // OK、バッファは変更可能であり、必ず'\0'を含む

ひっかけ問題

次のコードの実行結果は何で、どのようなエラーを引き起こしますか?

char *str = "hello"; str[0] = 'H'; printf("%s\n", str);

答え: プログラムは未定義の動作を引き起こし、恐らくセグメンテーションフォルトになります。なぜなら、文字列リテラルは読み取り専用のメモリ領域に配置され、文字列リテラルのアドレスに値を書き込むことはできません。

このテーマに関する実際のエラーの例


事例 チームは文字列配列とリテラルポインタの概念を混同しました。ある関数がchar *output = "default";を受け取り、その後strcpy(output, input);を実行したため、最初の実行でクラッシュしました。なぜなら、コピーは読み取り専用メモリに行われたからです。


事例 ネットワーク操作中、結果がバッファに保存され、char *buf = NULL; strcpy(buf, data);で確保されました。これにより、未初期化メモリへの書き込みが行われ、アプリケーションがクラッシュしました。


事例 ローカライズ用のパッケージでは、チームがコンポーネント間で文字列を渡す際に\0が追加されていることを確認しませんでした。あるとき、関数がコンソールにゴミを出力し、内部のメモリ構造を損傷しました。