摘要:【斐登|C++最危险的代码,未做准备,请勿使用。不然只会在最后害了自己|C++】如果您不走运,可以将整数写在随后执行的代码之上,几乎任何事情都可能发生。伪造的代码可能会损坏关键的操作系统文件,或者广播对某人的侮辱性侮辱。将存储在你电脑的任何东...
按关键词阅读:

文章图片

我认为C ++中最危险的代码行是这样的:
Fred[8472
= 8743872;
这看起来平平无奇 , 但是如果Fred定义为具有8000个元素 , 那么该行代码将尝试将整数8743872写入RAM中的某个未知位置 。 从中得出的结果几乎可以是任何东西 。
如果幸运的话 , 操作系统(或程序本身)将识别出已尝试进行非法的内存访问 , 它将在屏幕上显示一条错误消息 , 并且程序将终止 。
如果您不走运 , 可以将整数写在随后执行的代码之上 , 几乎任何事情都可能发生 。 伪造的代码可能会损坏关键的操作系统文件 , 或者广播对某人的侮辱性侮辱 。 将存储在你电脑的任何东西公布在外等等 。
所以不要那样做 。 如果您觉得必须在C或C ++中使用数组 , 请务必仔细检查边界 。 无论您做什么 , 都不要编写这样的程序:
#include <stdio.h>
int main(void)
{
int Fred [505
= {0;
Fred[634
= 87592;
printf(“ Fred [634
=%d \\ n” , Fred [634
);
return 0;
在我的系统上 , 即使带有沉重的警告标志 , 我的编译器(gcc / g ++)也会在没有错误或警告的情况下进行编译!而且它运行时没有错误或警告 , 并给出了预期的结果!但是源代码正在提交非法的内存访问 , 并命令覆盖它实际上并不拥有的内存!
那么 , 为什么不引起编译器警告和/或运行时错误呢?因为优化!编译器看到我甚至没有接近填充数组 , 便默默地将“ 87592”的索引从“ 634”更改为“ 0” 。
但 , 如果几年后有人更改了程序怎么办?所做的更改可能会带来灾难性的后果 , 导致编译器无法进行优化:
#include <cstdio>
int main(void)
{
int Fred [500
;
int i
for(i = 0; i <100000; ++ i)
{
Fred [i
= i;
printf(“ Fred [34927
=%d \\ n” , Fred [34927
);
return 0;
编译字符串:
g ++ -I / rhe / include -D PLATFORM_IS_WIN64 -Wall -Wextra -Wfloat-equal -Wshadow -Wcast-qual -Wcast-align -Wconversion -Wcomments -Wundef -Wunused-macros -Wold-style-cast -Woverloaded-virtual -finput -charset = UTF-8 -std = gnu ++ 14 -s -O2 evil-test-2.cpp -L / rhe / lib64 -L / lib -L / usr / lib -lm -o / rhe / bin64 / test /evil-test-2.exe
编译器警告问题:
evil-test-2.cpp: In function ‘int main()’:
evil-test-2.cpp:9:15: warning: iteration 500 invokes undefined behavior [-Waggressive-loop-optimizations
Fred[i
= i;
~~~~~~~~^~~
evil-test-2.cpp:7:20: note: within this loop
for ( i = 0 ; i < 100000 ; ++i )
~~^~~~~~~~
evil-test-2.cpp:11:10: warning: array subscript is above array bounds [-Warray-bounds
printf(\"Fred[34927
= %d\\" Fred[34927
);
~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
运行时结果:
$ evil-test-2
Segmentation fault (core dumped)
这次 , 编译器无法优化问题 , 一切都崩溃了 。
所以 , 千万不能指望总是能逃脱马虎代码!没有任何编程语言!出于各种原因 , 您也许可以在短期内摆脱困境(例如 , 如上例所示 , 通过编译器优化为您修复错误) , 但从长期来看 , 它会再次咬住您 , 以非常糟糕的方式(程序崩溃 , 系统崩溃 , 硬件损坏 , 数据丢失 , 财务损失或甚至更糟) 。 所以不要那样做!
【斐登|C++最危险的代码,未做准备,请勿使用。不然只会在最后害了自己】特别地 , 在C ++编程语言中 , 除非绝对需要 , 否则您根本不应该使用数组或指针 , 除非您知道自己在做什么并且正在使用仔细且频繁的边界检查 。 而是使用“标准模板库”(简称“ STL”)提供的“容器” , “迭代器”和“算法” 。 STL存在 , 可以使用 , 如果您使用C ++编写 , 则应大量使用它 。 具体来说 , 在C中要使用数组的大多数事物都使用“矢量”模板 。 对矢量对象(而不是[花括号
)使用“ .at()”方法来调用自动边界检查 。

来源:(还能说晚安吗)
【】网址:/a/2021/0304/kd760916.html
标题:斐登|C++最危险的代码,未做准备,请勿使用。不然只会在最后害了自己