C ++ поврежденный стек вокруг переменной - PullRequest
0 голосов
/ 23 мая 2018

Я получаю сообщение об ошибке в функции, которую использую.Вся программа предназначена для печати римской цифры или целого числа, если пользователь дает римскую цифру или целое число.

Эта функция, в частности, предназначена для вычисления римского числа, когда ему дано целое число.Теперь он отправляет меня в _fastfail (все еще новый, я не видел этого раньше).«Подробности копирования» Fastfail получает следующее:

«Необработанное исключение в 0x0137CFE9 в HughesProject9.0.exe: код инструментария cookie стека обнаружил переполнение буфера на основе стека.».

Когда он работал, целое число в верхней части функции отбрасывало правильное «целое число» назад, и то же самое с счетчиком.Вот функция:

string intToRoman(int integer)
{
    char romanArray[10];
    int M = 0;
    int D = 0;
    int C = 0;
    int L = 0;
    int X = 0;
    int V = 0;
    int I = 0;
    int counter = 0;
    int i = 0;

    M = integer / 1000;
    D = ((integer % 1000) / 500);
    C = ((integer % 500) / 100);
    L = ((integer % 100) / 50);
    X = ((integer % 50) / 10);
    V = ((integer % 10) / 5);
    I = (integer % 5);
    counter = M + D + C + L + X + V + I;
    cout << "Integer: " << integer;
    cout << "Counter: " << counter;

    while (counter > 0)
    {
        for (int j = 0; j < 10; j++)
        {
            if (M > 0)
            {
                romanArray[i] = 'M';
                i++;
                counter--;
            }
        }

        for (int j = 0; j < 3; j++)
        {
            if (D > 3)
            {
                romanArray[i] = 'C';
                i++;
                counter--;
            }
            else
            {
                romanArray[i] = 'D';
                i++;
                counter--;
            }
        }
        for (int j = 0; j < 3; j++)
        {
            if (C > 3)
            {
                romanArray[i] = 'L';
                i++;
                counter--;
            }
            else
            {
                romanArray[i] = 'C';
                i++;
                counter--;
            }
        }
        for (int j = 0; j < 3; j++)
        {
            if (L > 3)
            {
                romanArray[i] = 'X';
                i++;
                counter--;
            }
            else
            {
                romanArray[i] = 'L';
                i++;
                counter--;
            }
        }
        for (int j = 0; j < 3; j++)
        {
            if (X > 3)
            {
                romanArray[i] = 'V';
                i++;
                counter--;
            }
            else
            {
                romanArray[i] = 'X';
                i++;
                counter--;
            }
        }
        for (int j = 0; j < 3; j++)
        {
            if (V > 3)
            {
                romanArray[i] = 'I';
                i++;
                counter--;
            }
            else
            {
                romanArray[i] = 'V';
                i++;
                counter--;
            }
        }
        for (int j = 0; j < 3; j++)
        {
            if (I > 0)
            {
                romanArray[i] = 'I';
                i++;
                counter--;
            }
        }

        string calcRoman(romanArray);

        return calcRoman;
    }
}

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Вот как вы можете отлаживать свой код и точно видеть, что происходит не так.Я думаю, вам будет проще просто продумать свой код (потому что он неправильный во многих отношениях, чем просто уничтожать стек), но ... Буквально набрав «run» в gdb, вы попадете прямо к проблеме.

Перейдите сюда, исправьте код, который вы опубликовали, чтобы он компилировался (добавьте main с вызовом вашей функции, скажем, 50000, и заголовками, и using namespace std) https://www.onlinegdb.com/# Нажмите отладку, затем

Reading symbols from /home/a.out...done.                                                                             
(gdb) run                                                                                                            
Starting program: /home/a.out                                                                                        
*** stack smashing detected ***: /home/a.out terminated                                                              
Integer: 50000Counter: 50                                                                                            
Program received signal SIGABRT, Aborted.                                                                            
0x00007ffff7520f79 in __GI_raise (sig=sig@entry=6)                                                                   
    at ../nptl/sysdeps/unix/sysv/linux/raise.c:56                                                                    
56      ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.                                          
(gdb) #examine the call stack                                                                                        
(gdb) bt                                                                                                             
#0  0x00007ffff7520f79 in __GI_raise (sig=sig@entry=6)                                                               
    at ../nptl/sysdeps/unix/sysv/linux/raise.c:56                                                                    
#1  0x00007ffff7524388 in __GI_abort () at abort.c:89                                                                
#2  0x00007ffff755e1d4 in __libc_message (do_abort=do_abort@entry=1,                                                 
    fmt=fmt@entry=0x7ffff766a415 "*** %s ***: %s terminated\n")                                                      
    at ../sysdeps/posix/libc_fatal.c:175                                                                             
#3  0x00007ffff75f5b2c in __GI___fortify_fail (msg=<optimized out>,                                                  
    msg@entry=0x7ffff766a3fd "stack smashing detected") at fortify_fail.c:37                                         
#4  0x00007ffff75f5ad0 in __stack_chk_fail () at stack_chk_fail.c:28                                                 
#5  0x0000000000400ff3 in intToRoman (integer=50000) at main.cpp:139                                                 
#6  0x0000000000401017 in main () at main.cpp:144                                                                    
(gdb) #go to the code we recognize                                                                                   
(gdb) f 5                                                                                                            
#5  0x0000000000400ff3 in intToRoman (integer=50000) at main.cpp:139                                                 
139     }                                                                                                            
(gdb) #examine our index variable                                                                                    
(gdb) p i                                                                                                            
$1 = 25                                                                                                              
(gdb)    

Теперь ...

(gdb) #restart so we can watch code execute                                                                          
(gdb) b main                                                                                                         
Breakpoint 1 at 0x401006: file main.cpp, line 144.                                                                   
(gdb) run                                                                                                            
The program being debugged has been started already.                                                                 
Start it from the beginning? (y or n) y                                                                              
Starting program: /home/a.out                                                                                        

Breakpoint 1, main () at main.cpp:144                                                                                
144       printf ("%s", intToRoman (50000).c_str ());                                                                
(gdb) #step into function                                                                                            
(gdb) s                                                                                                              
intToRoman (integer=50000) at main.cpp:15                                                                            
15      {                                                                                                            
(gdb) #run next line                                                                                                 
(gdb) n                                                                                                              
17        int M = 0;                                                                                                 
(gdb) #etc...                                                                                                        
(gdb) n                            

Другая вещь, которую вы можете сделать здесь, когда я нахожусь в области видимости (как только вы вошли в intToRoman()), вы можете установить часы на i,вот так:

rwatch i if i >=10 Затем c (продолжение).Это позволит программе работать до тех пор, пока код не прочитает i, а i -> = 10.

0 голосов
/ 23 мая 2018

Я не думаю, что ваш алгоритм генерации эквивалента римской цифры правильный.Я передал 100, и это массив, который он строил

i 0    ╠╠╠╠╠╠╠╠╠╠
i 3    DDD╠╠╠╠╠╠╠
i 6    DDDCCC╠╠╠╠
i 9    DDDCCCLLL╠
i 12    DDDCCCLLLX
i 15    DDDCCCLLLX
i 15    DDDCCCLLLX

, который, конечно, не является римской цифрой для 100. Похоже, вам нужно перепроверить else части вашего for циклы, они вставляют символы, когда они не нужны

    for (int j = 0; j < 3; j++)
    {
        if (D > 3)
        {
            romanArray[i] = 'C';
            i++;
            counter--;
        } else
        {
            romanArray[i] = 'D';
            i++;
            counter--;
        }
    }

D был равен нулю, но этот код все еще вставляет 3 "DDD".Вам, вероятно, нужно что-то вроде

} else if (D > 0) {
...