2016-12-04 7 views
0

文字から文字(たとえば2番目の文字)を置き換えたい。 私のコードで何が問題になっていますか?それはコンパイルすることができますが、私が必要とするものを実行する代わりに、私にセグメンテーションの誤りを与えます。ありがとう!私のコード文字列の文字を置換することでCのセグメンテーション違反が発生する

~/workspace/pset2/crack/ $ clang -ggdb3 -O0 -std=c11 -Wall -Werror -Wshadow bug.c -lcrypt -lcs50 -lm -o bug 
~/workspace/pset2/crack/ $ ./bug 
Segmentation fault 

答えて

0

は、あなたの"abcd"が文字列リテラルとして知られているものであり、プログラムの読み出し専用メモリ空間に属している、それは(変更することはできませんとにかくそれはまともな運用システムの下で実行されていない場合)。

stringは、基本的にはchar *ポインターであり、任意のメモリースペースを指し、読み取り専用スペースにあるかどうかは気にしないからです。 (C++ std::stringと混同しないでください)。

変更可能にするには、ポインタではなく配列であることをCに伝える必要があります。

char key[] = "abcd"; 

ここで、Cはこの文字列をスタックに配置して自由に変更できます。

0
string key="abcd"; 

stringをコンパイル

#define _XOPEN_SOURCE 
#include <unistd.h> 
#include <stdio.h> 
#include <cs50.h> 
#include <string.h> 

int main (int argc, string argv[]) 
{ 
    string key="abcd"; 
    key[1]='f'; 
} 

以降はkeyが文字列リテラルで、基本的にchar *です。それを変更しようとします。したがって、セグメンテーションの誤りです。

0

名前の定義は表示されませんが、それはchar *のようなものだと思います。

したがってこの宣言

string key="abcd"; 

にリテラル文字列へのポインタが宣言されます。

文字列リテラルはC言語で修正されていません。文字列リテラルを変更しようとすると、未定義の動作が発生します。 C標準(6.4.5文字列リテラル)から

7は、それら 要素が適切な値を持って設けられ、これらの配列が異なっているかどうかを指定されていません。 プログラムが にそのような配列を変更しようとすると、動作は未定義です。それがどこにあるだけで、ヒープまたはスタックにあるメモリを変更することができます

+0

'STRING'は' cs50'と呼ばれるライブラリからのtypedefで、あなたはそれが正しいだ - それは唯一の 'シャア* '。どうやら、このライブラリはハーバードの入門コースでキーボードから読むために使われているようです。役に立つと思うが、このtypedefは本当に存在すべきではない。 – giusti

+0

@giusti情報あり​​がとうございます:) –

0

これは、実際にkey変数に"abcd"がコピーされていないためです。 代わりに、keyはこの定数文字列へのポインタです。

あなたはそれを変更することができるようにしたい場合は、あなたがこれを行うことができます:

int main (int argc, string argv[]) 
{ 
    char key[] = { "some string" }; 
    key[1]='f'; 
} 
関連する問題