Как всегда, проблемы с указателями. Я пытаюсь создать очень простую функцию «шифрование / дешифрование» для массивов символов. Да, я знаю, что могу использовать строки, но я хочу улучшить свои знания об указателях и использовать простые байты для выполнения простой задачи.
Итак, я создал простую структуру, как это:
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 ++. Что я опять сделал? Спасибо!
mytext.value = new char[5];
mytext.value = "Hello";
во второй строке вы отбрасываете (дескриптор) выделенную память, вытекаете ее и позволяете 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
будет лучшим выбором здесь.
Вы модифицируете строковые литералы:
mytext.value = "Hello";
после этого вы больше не можете законно мутировать то, что mytext.value
указывает на, вы можете только переназначить указатель.
Исправление: использование std::string