变量周围的 C++ 损坏堆栈
C++ Corrupt stack around Variable
我在使用的函数中遇到错误。整个程序旨在在用户给出罗马数字或整数时打印罗马数字或整数。
此函数特别用于在给定整数时计算罗马数字。它现在将我发送到 _fastfail(还是新的,我以前没见过)。 Fastfail 的 "copy details" 得到这个:
"Unhandled exception at 0x0137CFE9 in HughesProject9.0.exe: Stack cookie instrumentation code detected a stack-based buffer overrun. occurred".
当它是运行时,函数顶部的整数将正确的"integer"抛回,与计数器相同。这是函数:
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;
}
}
我认为您生成等效罗马数字的算法不正确。我传入了100
,这是它构造的数组
i 0 ╠╠╠╠╠╠╠╠╠╠
i 3 DDD╠╠╠╠╠╠╠
i 6 DDDCCC╠╠╠╠
i 9 DDDCCCLLL╠
i 12 DDDCCCLLLX
i 15 DDDCCCLLLX
i 15 DDDCCCLLLX
这肯定不是 100 的罗马数字。看来您需要重新检查 for
循环的 else
部分,它们在不需要时插入字符
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) {
您可以通过以下方式调试代码并准确了解问题所在。我认为你会发现仔细思考你的代码会更容易(因为它在很多方面都是错误的,而不仅仅是破坏堆栈),但是......直接在 gdb 中输入 "run" 会让你直接找到问题所在。
转到此处,修复您发布的代码以便编译(添加 main,用 50000 和 headers 和 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
= 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
你可以在这里做的另一件事是一旦 i 在范围内(一旦你进入 intToRoman()
),你可以在 i 上设置监视,如下所示:
rwatch i if i >=10
然后 c
(继续)。这只会让程序 运行 直到代码读取 i
而 i
>= 10.
我在使用的函数中遇到错误。整个程序旨在在用户给出罗马数字或整数时打印罗马数字或整数。
此函数特别用于在给定整数时计算罗马数字。它现在将我发送到 _fastfail(还是新的,我以前没见过)。 Fastfail 的 "copy details" 得到这个:
"Unhandled exception at 0x0137CFE9 in HughesProject9.0.exe: Stack cookie instrumentation code detected a stack-based buffer overrun. occurred".
当它是运行时,函数顶部的整数将正确的"integer"抛回,与计数器相同。这是函数:
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;
}
}
我认为您生成等效罗马数字的算法不正确。我传入了100
,这是它构造的数组
i 0 ╠╠╠╠╠╠╠╠╠╠
i 3 DDD╠╠╠╠╠╠╠
i 6 DDDCCC╠╠╠╠
i 9 DDDCCCLLL╠
i 12 DDDCCCLLLX
i 15 DDDCCCLLLX
i 15 DDDCCCLLLX
这肯定不是 100 的罗马数字。看来您需要重新检查 for
循环的 else
部分,它们在不需要时插入字符
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) {
您可以通过以下方式调试代码并准确了解问题所在。我认为你会发现仔细思考你的代码会更容易(因为它在很多方面都是错误的,而不仅仅是破坏堆栈),但是......直接在 gdb 中输入 "run" 会让你直接找到问题所在。
转到此处,修复您发布的代码以便编译(添加 main,用 50000 和 headers 和 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
= 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
你可以在这里做的另一件事是一旦 i 在范围内(一旦你进入 intToRoman()
),你可以在 i 上设置监视,如下所示:
rwatch i if i >=10
然后 c
(继续)。这只会让程序 运行 直到代码读取 i
而 i
>= 10.