Run-Time Check Failure #2 - Stack around the variable 'Opad' was corrupted

125
05 декабря 2020, 21:50

Дан текст, среди символов которого имеется пробел. Группа символов, предшествующая первому пробелу, представляет собой русское слово (существительное мужского рода, оканчивающееся на -ок; после первого пробела идет одна из букв и,р,д,в,т,п указывающая на падеж. Получить данное слово в указанном падеже.

Сам алгоритм организован по сути верно, но в конце программы выдает следующую ошибку: Run-Time Check Failure #2 - Stack around the variable 'oPad' was corrupted. ПОМОГИТЕ!!!!!! Что ему не так??? (Были догадки,что в момент ,когда находимся на "т" падеже он не умещается в массив, но даже если закомментить этот кусок ошибка все равно остается.)Работаю в Visual Studio.

#include <iostream>
#include <stdio.h>
#include <cctype>
using namespace std;
void obnul(char*str){
    for (int i=0;str[i]!='\0';i++)
        str[i]=0;
}
void give_pad(char pad,char *oPad) {
    if (pad == 'и') 
    {
     oPad[0]='о';
     oPad[1]='к';
    }
    else if (pad=='р')
    {
        oPad[0]='к';
        oPad[1]='а';
    }
    else if (pad=='д')
    {
        oPad[0]='к';
        oPad[1]='у';
    }
    else if (pad=='в')
    {
        oPad[0]='к';
        oPad[1]='а';
    }
    else if (pad=='т')
    {
        oPad[0]='к';
        oPad[1]='о';
        oPad[2]='м';
    }
    else if (pad=='п')
    {
        oPad[0]='к';
        oPad[1]='е';
    }                       
}

void print_ind(char *str,int ind) {
    cout << "Programma vernula: " << endl;
    for (int i=0;i<ind;i++)
    {
        cout << str[i];}
    cout << endl;
}
bool isklych(char *str) {
int j=0;
    for (int i=0;str[i]!='\0';i++){
    if (str[i-1]=='о' && str[i]=='к' && (str[i-2]=='р' || str[i-2]=='к' || str[i-2]=='л' || str[i-2]=='т')) {
        j=1;
    }
    }
return j;
}

int izmen_iskl(char*str,char *oPad,int size,bool is) {
int j=0,
    z=0;
    for (int i=0;i<size;++i)
    {
        if (!is && str[i]=='о')
        {
            str[i]=str[i+1];
            z++;
        }
        if ((str[i-1]=='о' && str[i]=='к' && str[i+1]=='\0') || z>=1)
        {
            if (str[i-1]==oPad[j])
            { j++;
            }
            else if (!(str[i-1]==oPad[j])||!is)
            {
                str[i]=oPad[j];
                j++;
            }
            z++;
        }
    }   
print_ind(str,size);
    return 0;
}
void izmennadr(char *str,char *oPad) {
int size; char prstr;
    size=strlen(oPad)+strlen(str);
    if (strlen(str)==3)
    {
        cout << "Исключение: суще-ное из 3-х букв" << endl;
        int is=1;
        izmen_iskl(str,oPad,size,is);
    }
    else if (strlen(str)>3 && isklych(str))
    {
     cout << "Исключение: суще-ное имеет окончание на -кок/-рок/-лок/-ток" << endl;
        int is=1;
        izmen_iskl(str,oPad,size,is);
    }
    else
    {
        cout << "Слово не принадлежит исключениям" << endl;
        int is=0;
        izmen_iskl(str,oPad,size,is);
    } 
}

int main()
{
    char str[255],pad;
    obnul(str);
    char oPad[2]; 
    obnul(oPad);
    for (int i=0;i<2;++i)
    {
        if (i==0)
        {
            cin>>str;
         cout << "Слово:" << str << endl;
        }
        else if (i==1) {
            cin>>pad;
            cout << "Падеж" << pad << endl;
            give_pad(pad,oPad);
        }
    }
 izmennadr(str,oPad);
    return 0;
}
Answer 1

Весь код набит явными и неявными вылетами за пределы массива.

  • В функцию obnul передаются неинициализированные массивы. Она итерирует пока не найдет в них \0. Откуда в неинициализированном массиве вдруг возьмется \0?

    Зачем вообще понадобилась эта функция, когда в С++ можно обнулить массив встроенным средствами языка, сразу при объявлении?

      char str[255] = {};
    
  • Массив oPad имеет размер 2. А в give_pad у вас внезапно oPad[2]='м' - очевидный вылет за пределы массива.

Answer 2

Вы слышком усложняете все. Чем больше усложняете, тем больше вероятность ошибок. Лучше напишите просто:

char str[50], pod;
/*для одного русского слова достаточно 
  занять память и на 50 символов */
cin >> str >> pod;
// изменению подлежат последные два символа
size_t  k = strlen(str) - 2;
switch (pod) {
case 'p':
case 'в':   strcpy(str + k, "ka");
    break;
case 'д':   strcpy(str + k, "kу");
    break;
case 'т':    strcpy(str + k, "ком");
    break;
case 'п':       strcpy(str + k, "ke");
    break;
default:
    if (pod != 'i') {
        cerr << "неправильный падеж";
        exit(1);
    }
}
cout <<  "ваше слово:  " << str;

А вот на C++:

std::string s; char pod;
cin >> s >> pod;
if (pod != 'и') {
    std::unordered_map<char, std::string>
    table{{'р', "ка"}, {'в', "ка"}, {'д', "ку"}, {'т', "ком"}, {'п', "ке"}};
    s.erase(s.begin() + s.length() -2);
    s += table[pod];
}
cout << s;
Answer 3

Убрали функцию obnul, увеличили размерность oPad Помогите !!!! Что еще сделать?

#include <iostream>
#include <stdio.h>
#include <cctype>
using namespace std;

void give_pad(char pad,char *oPad) {
    if (pad == 'и') 
    {
     oPad[0]='о';
     oPad[1]='к';
    }
    else if (pad=='р')
    {
        oPad[0]='к';
        oPad[1]='а';
    }
    else if (pad=='д')
    {
        oPad[0]='к';
        oPad[1]='у';
    }
    else if (pad=='в')
    {
        oPad[0]='к';
        oPad[1]='а';
    }
    else if (pad=='т')
    {
        oPad[0]='к';
        oPad[1]='о';
        oPad[2]='м';
    }
    else if (pad=='п')
    {
        oPad[0]='к';
        oPad[1]='е';
    }                       
}

void print_ind(char *str,int ind) {
    cout << "Programma vernula: " << endl;
    for (int i=0;i<ind;i++)
    {
        cout << str[i];}
    cout << endl;
}
bool isklych(char *str) {
int j=0;
    for (int i=0;str[i]!='\0';i++){
    if (str[i-1]=='о' && str[i]=='к' && (str[i-2]=='р' || str[i-2]=='к' || str[i-2]=='л' || str[i-2]=='т')) {
        j=1;
    }
    }
return j;
}

int izmen_iskl(char*str,char *oPad,int size,bool is) {
int j=0,
    z=0;
    for (int i=0;i<size;++i)
    {
        if (!is && str[i]=='о')
        {
            str[i]=str[i+1];
            z++;
        }
        if ((str[i-1]=='о' && str[i]=='к' && str[i+1]=='\0') || z>=1)
        {
            if (str[i-1]==oPad[j])
            { j++;
            }
            else if (!(str[i-1]==oPad[j])||!is)
            {
                str[i]=oPad[j];
                j++;
            }
            z++;
        }
    }   
print_ind(str,size);
    return 0;
}
void izmennadr(char *str,char *oPad) {
int size; char prstr;
    size=strlen(oPad)+strlen(str);
    if (strlen(str)==3)
    {
        cout << "Исключение: суще-ное из 3-х букв" << endl;
        int is=1;
        izmen_iskl(str,oPad,size,is);
    }
    else if (strlen(str)>3 && isklych(str))
    {
     cout << "Исключение: суще-ное имеет окончание на -кок/-рок/-лок/-ток" << endl;
        int is=1;
        izmen_iskl(str,oPad,size,is);
    }
    else
    {
        cout << "Слово не принадлежит исключениям" << endl;
        int is=0;
        izmen_iskl(str,oPad,size,is);
    } 
}

int main()
{   char pad;
    char str[255]={};
    char oPad[3]={};
    for (int i=0;i<2;++i)
    {
        if (i==0)
        {
            cin>>str;
         cout << "Слово:" << str << endl;
        }
        else if (i==1) {
            cin>>pad;
            cout << "Падеж" << pad << endl;
            give_pad(pad,oPad);
        }
    }
 izmennadr(str,oPad);
    return 0;
}
READ ALSO
Air Datepicker: получить диапазон даты в строке URL

Air Datepicker: получить диапазон даты в строке URL

jQuery календарь Air DatepickerВ коде предлагаю способ получения диапазона даты в строке URL

121
SVG анимация текста и линий

SVG анимация текста и линий

Как можно сделать анимацию рисования линии от верха к первому тексту, затем появления текста и также с остальными линиями и текстом?

127
Media запросы работают не корректно

Media запросы работают не корректно

Верстаю одностраничник, пытаюсь адаптировать под мобильные устройства

129
после нажатия alt , ctrl не отлавливает WPF

после нажатия alt , ctrl не отлавливает WPF

После нажатия Аlt, Ctrl не отлавливаетНужно ПРОСТО нажать Alt снова,чтобы CTRL снова начал отлавливать

131