Необработанное исключение: нарушение прав на чтение. this-> String было 0x1C6F112 - PullRequest
0 голосов
/ 06 марта 2019

Поэтому я пишу код, который шифрует и вводит, переключая букву на букву после нее, используя формулу ai = letter ((position (ai) + position (ai + 1)) mod k) где k - количество букв в алфавите.

Теперь вот мой код;

using namespace std;

class Encrypt {
private:
    char letters[27];
    char *String = new char[500];
    char letters_cipher[25];
    unsigned int i, k;
public:
    Encrypt() :letters{ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' } {

        for (unsigned int i = 0; i < strlen(String); i++) {
            String[i] = '\0';
        }
    }
    ~Encrypt() {
        delete[] String;
    }
    void GetString() {
        cout << "Enter String : ";
        std::cin >> String;
    }

    void encrypt() {
        for (i = 1; i <= 26; i++) { // Run 26 times (1 for each letter)
            letters_cipher[i] = letters[(i + (i + 1)) % 26];
            cout << letters_cipher[i] << endl;
        }
        for (i = 0; i <= (strlen(String) - 1); i++) { // individual characters of string x can be referenced by x[0] etc
            for (k = 0; k <= 25; k++) {
                if (String[i] == letters[k]) {
                    cout << letters_cipher[k];
                }
            }
        }
    }

    void Print() {
        for (unsigned int i = 0; i < strlen(letters_cipher); i++) {
            cout << letters_cipher[i];
        }
    }

};

Я получаю следующую ошибку

Исключение: нарушение прав на чтение. this-> String было 0x128F112.

для строки:

if (String [i] == букв [k])

Есть идеи, как мне это исправить?

EDIT:

Я сделал некоторые изменения в коде, и это выглядит следующим образом:

class Encrypt {
private:
    char letters[27];
    char *String = new char[500];
    char letters_cipher[27];
    unsigned int i, k;
public:
    Encrypt() :letters{ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' } {

        for (unsigned int i = 0; i < 500; i++) {
            String[i] = '\0';
        }
    }
    ~Encrypt() {
        delete[] String;
    }
    void GetString() {
        cout << "Enter String : ";
        std::cin >> String;
    }

    void encrypt() {
        for (i = 1; i <= 26; i++) { // Run 26 times (1 for each letter)
            letters_cipher[i] = letters[(i + (i + 1)) % 26];
            cout << letters_cipher[i] << endl;
        }
        for (i = 0; i <= (sizeof(String) - 1); i++) { // individual characters of string x can be referenced by x[0] etc
            for (k = 0; k <= 25; k++) {
                if (String[i] == letters[k]) {
                    cout << letters_cipher[k];
                }
            }
        }
    }

    void Print() {
        for (unsigned int i = 0; i < sizeof(letters_cipher); i++) {
            cout << letters_cipher[i];
        }
    }

};

ошибки больше нет, программа запускается, но закрывается с ошибкой;

«ConsoleApplication5.exe» (Win32): загружен «C: \ Windows \ SysWOW64 \ kernel.appcore.dll». Не удается найти или открыть PDB файл. 'ConsoleApplication5.exe' (Win32): загружен "C: \ Windows \ SysWOW64 \ msvcrt.dll. Не удается найти или открыть файл PDB. 'ConsoleApplication5.exe' (Win32): загружен "C: \ Windows \ SysWOW64 \ rpcrt4.dll. Не удается найти или открыть файл PDB. 'ConsoleApplication5.exe' (Win32): загружен "C: \ Windows \ SysWOW64 \ sspicli.dll. Не удается найти или открыть файл PDB. 'ConsoleApplication5.exe' (Win32): загружен "C: \ Windows \ SysWOW64 \ cryptbase.dll. Не удается найти или открыть файл PDB. 'ConsoleApplication5.exe' (Win32): загружен "C: \ Windows \ SysWOW64 \ bcryptprimitives.dll. Не могу найти или открыть Файл PDB. 'ConsoleApplication5.exe' (Win32): загружен "C: \ Windows \ SysWOW64 \ sechost.dll. Не удается найти или открыть файл PDB. Программа «[20764] ConsoleApplication5.exe» вышла с кодом 0 (0x0).

1 Ответ

4 голосов
/ 06 марта 2019

в

    for (i = 1; i <= 26; i++) { // Run 26 times (1 for each letter)
        letters_cipher[i] = letters[(i + (i + 1)) % 26];

вы пишете 2 индекса из letters_cipher, являющегося char letters_cipher[25];, поведение не определено

и в

       for (k = 0; k <= 25; k++) {
            if (String[i] == letters[k]) {
                cout << letters_cipher[k];
            }

вы читаетеодин индекс из letters_cipher, поведение снова не определено

Максимально допустимый индекс в letters_cipher равен 24

Обратите внимание, что в

   for (unsigned int i = 0; i < strlen(letters_cipher); i++) {
        cout << letters_cipher[i];
    }

strlen(letters_cipher) тоже не будет работать, потому что нигде в вашем коде, где вы вводите в него нулевой символ конца, поэтому strlen также выйдет из инициализированной части letters_cipher и может быть снова из нее.

У вас также есть проблема в:

    for (unsigned int i = 0; i < strlen(String); i++) {
        String[i] = '\0';
    }

, потому что вы делаете strlen(String) первый цикл без инициализации String , замените его на 500 (или лучше используйте стандартный:: string)

Есть идеи, как я могу это исправить?

В общем случае не используйте числа типа 26 или 25 в своих циклах, используйте sizeof, и вы также можете использовать std :: vector вместо (C) массивов.Когда содержимое является постоянным, не делайте размер самостоятельно, поэтому для letters просто сделайте:

static const char letters_cipher[] = {
   'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
   'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
   'y', 'z'
};

Вероятно, letters_cipher должен иметь тот же размер, что и letters, и исправьте набор, потому что for начинаетсяна 1, а не 0

Дополнительные замечания

  • массив letters бесполезен, он содержит только буквы a..z, поэтому letters[i] это просто 'a' + i
  • вы делаете и using namespace std;, и std::xxx, выберите один из них (многие скажут, что вы не делаете using namespace std;)

Предложение, если яхорошо понимают ваш сценарий:

#include <iostream>
#include <string>

class Encrypt {
  private:
    std::string str;
    char letters_cipher['z' - 'a' + 1];

    inline char letter(size_t i) { return 'a' + i; } // to help
  public:
    Encrypt() {} // default definition is useless in fact
    ~Encrypt() {} // default definition is useless in fact

    bool Getstr() {
      std::cout << "Enter str : ";
     return (std::cin >> str); // to indicates EOF in case
    }

    void encrypt() {
      for (size_t i = 1; i <= sizeof(letters_cipher); i++) { // Run 26 times (1 for each letter)
        letters_cipher[i - 1] = letter((i + (i + 1)) % 26);
        std::cout << letters_cipher[i - 1] << std::endl;
      }
      for (size_t i = 0; i < str.length(); i++) { // individual characters of string x can be referenced by x[0] etc
        for (size_t k = 0; k < sizeof(letters_cipher); k++) {
          if (str[i] == letter(k)) {
            std::cout << letters_cipher[k];
          }
        }
      }
      std::cout << std::endl;
    }

    void Print() {
      for (size_t i = 0; i < sizeof(letters_cipher); i++) {
        std::cout << letters_cipher[i];
      }
      std::cout << std::endl;
    }
};

int main()
{
  Encrypt e;

  e.Getstr();
  e.encrypt();
  e.Print();
}

Компиляция и выполнение:

/tmp % g++ -pedantic -Wextra e.cc
/tmp % ./a.out
Enter str : azerty
d
f
h
j
l
n
p
r
t
v
x
z
b
d
f
h
j
l
n
p
r
t
v
x
z
b
dbllpz
dfhjlnprtvxzbdfhjlnprtvxzb

Выполнение под valgrind :

/tmp % valgrind ./a.out
==29157== Memcheck, a memory error detector
==29157== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==29157== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==29157== Command: ./a.out
==29157== 
Enter str : azerty
d
f
h
j
l
n
p
r
t
v
x
z
b
d
f
h
j
l
n
p
r
t
v
x
z
b
dbllpz
dfhjlnprtvxzbdfhjlnprtvxzb
==29157== 
==29157== HEAP SUMMARY:
==29157==     in use at exit: 0 bytes in 0 blocks
==29157==   total heap usage: 4 allocs, 4 frees, 115 bytes allocated
==29157== 
==29157== All heap blocks were freed -- no leaks are possible
==29157== 
==29157== For counts of detected and suppressed errors, rerun with: -v
==29157== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...