0

いつものように、ポインターの問題。文字配列用の非常に単純な「暗号化/復号化」関数を作成しようとしています。はい、文字列を使用できることはわかっていますが、ポインターに関する知識を向上させ、単純なバイトを使用して単純なタスクを達成したいと考えています。そこで、次のような単純な構造体を作成しました。

struct text {
    char* value;
    int size;
}

そして、この単純な関数を作成しました:

text encrypt(text decrypted) {
    char key = 'X';
    for (int i=0; i<decrypted.size; i++) {
        decrypted.value[i] = decrypted.value[i] ^ (key + i) % 255);
    }
    return decrypted;
}

この時点で、経験豊富な C++ プログラマーなら問題を発見できるはずです。とにかく、私はこの関数を次のように呼び出します:

...
text mytext;
mytext.value = new char[5];
mytext.value = "Hello";
mytext.size = 5;

mytext = encrypt(mytext);
...

いつものように、「セグメンテーション違反 (コア ダンプ)」エラーが発生します。これは Linux であり、もちろん g++ です。また、私は何をしましたか?ありがとう!

4

2 に答える 2

3
mytext.value = new char[5];
mytext.value = "Hello";

2行目では、割り当てられたメモリ(へのハンドル)を破棄してリークしmytext.value、文字列リテラルをポイントします。文字列リテラルは読み取り専用のメモリセグメントに格納されることが多いため、文字列リテラルの変更は未定義の動作であり、通常はクラッシュします。

を使用する場合char*は、割り当てられたメモリに文字列を挿入する必要strncpyがあります(ただし、0で終了しないことに注意してください。その場合は、を割り当ててnew char[6]、0ターミネータもコピーする必要があります)。

または、それが返すdecrypt新しいものを作成しましょう:text

text encrypt(text decrypted) {
    char key = 'X';
    text encrypted;
    encrypted.size = decrypted.size;
    encrypted.value = new char[encrypted.size];
    for (int i=0; i<decrypted.size; i++) {
        encrypted.value[i] = decrypted.value[i] ^ (key + i) % 255;
    }
    // What about 0-terminators?
    return encrypted;
}

ただし、C ++を使用しているstd::stringため、ここではより適切な選択になります。

于 2012-12-13T16:47:45.777 に答える
3

文字列リテラルを変更しています:

mytext.value = "Hello";

この後、ポイントを合法的に変更することはできなくなりmytext.value、ポインタを再割り当てすることしかできなくなります。

修正:使用std::string

于 2012-12-13T16:47:55.183 に答える