[解決済み] strtokのセグメンテーションフォールト
質問内容
以下のコードの断片がセグメンテーションフォールトを出す理由を理解しようとしています。
void tokenize(char* line)
{
char* cmd = strtok(line," ");
while (cmd != NULL)
{
printf ("%s\n",cmd);
cmd = strtok(NULL, " ");
}
}
int main(void)
{
tokenize("this is a test");
}
strtok() は実際には文字列リテラルに対してトークン化しないことは知っていますが、この場合。
line
は直接文字列
"this is a test"
の配列で、内部的には
char
. をトークン化する方法はありますか?
line
配列にコピーすることなく?
どのように解決するのですか?
問題は、文字列リテラルを変更しようとしていることです。 そうすると、プログラムの動作が不定になります。
文字列リテラルを変更してはいけないというのは、単純化しすぎです。 文字列リテラルは
const
は正しくありません。
警告。 以下、脱線します。
文字列リテラル
"this is a test"
は、型
char[15]
(長さが14で、終端である
'\0'
). この文脈を含むほとんどの場合,このような式は暗黙のうちに配列の最初の要素へのポインタに変換され,その型は
char*
.
文字列リテラルが参照する配列を変更しようとした場合の動作は未定義です。
const
(C標準では未定義と明記されているからです。
コンパイラによっては、これを許してくれるかもしれません。 あなたのコードは実際にリテラルに対応する静的配列を変更するかもしれません(これは後で大きな混乱を引き起こす可能性があります)。
しかし、最近のほとんどのコンパイラは、物理的なROMではなく、仮想メモリシステムによって変更から保護されているメモリの領域に、読み取り専用メモリに配列を格納します。 このようなメモリを変更しようとすると、通常セグメンテーションフォールトが発生し、プログラムがクラッシュします。
では、なぜ
はありません。
文字列リテラル
const
? このように、文字列を変更することは避けたいものですが、C++では文字列リテラルを作成することができます。
const
. その理由は歴史的なものです。 歴史的な理由で
const
キーワードは、1989年のANSI C規格で導入される以前には存在しませんでした(ただし、それ以前に一部のコンパイラで実装されていたと思われます)。 ですから、ANSI以前のプログラムは次のようなものです。
#include <stdio.h>
print_string(s)
char *s;
{
printf("%s\n", s);
}
main()
{
print_string("Hello, world");
}
ということを強制する方法がありませんでした。
print_string
が指す文字列を変更することは許されていません。
s
. 文字列リテラルの作成
const
ANSI Cの委員会は、既存のコードを破壊することを避けようとしました。 それ以来、言語にそのような変更を加える好機はありませんでした。 (C++の設計者、主にBjarne Stroustrupは、Cとの後方互換性についてはそれほど気にしていませんでした)。
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 `S_ISREG()` とは何ですか、そして何をするのですか?
-
[解決済み】式は変更可能なL値でなければならない
-
[解決済み】MB/sとMiB/sを計算する方法は?
-
[解決済み】sizeof float (3.0) vs (3.0f)
-
[解決済み】エラー:不明な型名'bool'
-
[解決済み] テスト
-
[解決済み】C言語のフォーマット文字列でデータ引数が使用されない [重複]。
-
[解決済み】なぜか。"エラー: 配列型を持つ式への代入"
-
[解決済み】宣言指定子で2つ以上のデータ型がある場合のエラー【非公開
-
[解決済み】C言語でpow( )への未定義参照、math.hを含むにもかかわらず【重複】。