Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么故意的缓冲区溢出不会覆盖变量?_C++_Buffer Overflow - Fatal编程技术网

C++ 为什么故意的缓冲区溢出不会覆盖变量?

C++ 为什么故意的缓冲区溢出不会覆盖变量?,c++,buffer-overflow,C++,Buffer Overflow,这可能是一个愚蠢的问题,因为我很确定这是不可能的,但如果是,请随时告诉我我做错了什么。 所以我一直在试验缓冲区溢出,以及C/C++中内存的工作原理,但我遇到了一些非常奇怪的事情 char arr[16]; char tmp = 33; strcpy(arr, "AAAAAAAAAA3211f11f2gg233h4h34h43AAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); cout << tmp << endl; char-arr[1

这可能是一个愚蠢的问题,因为我很确定这是不可能的,但如果是,请随时告诉我我做错了什么。 所以我一直在试验缓冲区溢出,以及C/C++中内存的工作原理,但我遇到了一些非常奇怪的事情

char arr[16];
char tmp = 33;

strcpy(arr, "AAAAAAAAAA3211f11f2gg233h4h34h43AAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBB");

cout << tmp << endl;
char-arr[16];
char-tmp=33;
strcpy(arr,“aaaaaaaaaaaaa 3211F11F2GG233H4H34H43aaaaaaaabbbbbbbbbbbbbbbbb”);

cout您的代码正在调用未定义的行为,因为您正在写入未分配的内存。任何事情都有可能发生,打印一个
'g'
,弄坏你的盒子,或者你的冰箱可能遭到袭击

在给出实际答案之前,我需要承认律师的回答:未定义的行为是未定义的。您询问了未定义行为的意外结果,但对于未定义行为的行为不应有任何期望

但实际的答案是,典型架构上的堆栈朝着较低的地址增长

因此,实际的预期是溢出
arr[]
将从当前函数的条目中丢弃保存的寄存器(可能包括返回地址),因此当该函数尝试返回时,会发生不好的事情

但是,在结构上晚于
arr[]
的堆栈上分配的内容将位于较低的地址,并且不会发生溢出。在最简单的未优化编译器行为中,
tmp
的分配晚于
arr
,因此是安全的


tmp
是安全的原因包含了足够多的编译器假设,即预测
tmp
是安全的或如果
tmp
不安全的话感到惊讶是荒谬的。但是
tmp
在该代码中安全的可能性仍然稍大。(保存的函数寄存器被破坏的可能性远远大于“有一点”。但即使这不是您可以信任的事情,也必然会发生)。

您的代码调用未定义的行为,这意味着-任何事情都可能发生:它可能成功,它可能崩溃,它可以做任何事情,并且仍然符合标准。引用:“我遇到了一些非常奇怪的事情“-是的,它甚至有一个名称:未定义的行为。不要试图解释它…这个答案只是让我想起了我的一个同事,他通过在函数的堆栈上放置空字符数组修复了一个崩溃…无论是在工作中还是在在线论坛中,我经常发现自己很难让其他程序员理解一个基本事实:代码更改消除了未定义行为的明显症状,没有修复错误,并且在代码和时间上与错误都非常遥远。非常有用,感谢您提供的信息。我发现先声明tmp,然后声明arr将实际覆盖tmp,因此我必须问:如果在上面的代码中,溢出溢出到arr之前声明的变量中,而没有溢出,是否可能损坏另一个进程的内存?(可能也会崩溃),我知道我不应该对这种代码有什么期望,我问的是,是否有可能破坏一个进程和另一个进程。在实践中,OS规则分离过程优先于C++规则,未定义的行为可以做任何事情。没有C++语言的律师会同意,但实际上,其他的过程是安全的。此外,您认为“在”
arr
之前”没有声明变量的假设是不正确的。在任何调用此函数的函数中声明的变量都会受到
arr
溢出的影响。如果此函数是
main
,您可能不知道某个名为它的隐藏函数,但事实上,它是由C++运行时库的一部分调用的,并且可能会破坏该函数的变量。要真正地将理论扩展到实践中:有一些请求可以使操作系统明确地告诉OS去浪费其他进程。理论上,此进程中未定义的行为可能是向操作系统发出请求,以丢弃另一个进程。因此,在得出其他过程是安全的结论之前,你需要在理论和实践之间划出一些界限。根据定义,这一边界在理论上是不安全的。
cout << arr[20] << endl;