缓冲区溢出不影响常量变量
buffer overflow not affecting const variable?
我对黑客,c,汇编,内存和所有这些东西了解不多,所以我无法自己解决我的问题。
因此,缓冲区溢出溢出到变量的其他地址并损坏它们。所以我测试了,它确实如此。而且我认为,如果它可以溢出恒定变量缓冲区溢出必须是超级强大的,我测试过,但它不会溢出常量变量。
为什么?
int a;
char buffer[8];
和
const int a;
char buffer[8];
变量"缓冲区"的地址位于变量"a"的地址前面,按"缓冲区"的大小。当分配给内存时,const 变量中有什么特殊之处吗?
我的示例代码:
#include <stdio.h>
#include <string.h>
int main() {
char buffer1[8];
const int a=0; //vs int a=0;
char buffer2[8];
strcpy(buffer1,"one");
strcpy(buffer2,"two");
printf("Buffer 2 [%p]: %sn",buffer2,buffer2);
printf("a [%p]: %dn",&a,a);
printf("Buffer 1 [%p]: %sn",buffer1,buffer1);
printf("nCopy Buffernn");
strcpy(buffer2,"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
printf("Buffer 2 [%p]: %sn",buffer2,buffer2);
printf("a [%p]: %dn",&a,a);
printf("Buffer 1 [%p]: %sn",buffer1,buffer1);
return 0;
}
我想到了三件事:
- 这是未定义的行为,因此所有赌注都不在桌面上。
- 编译器甚至不必查看
a
是什么。如果我是一个编译器,我只会看着代码并说"a
总是零,所以我将继续用0
替换a
。问题是,当你说printf("%p %d", &a, a);
时,编译器甚至不必获取a
的内容。它知道它将永远为零。 因此,它可以将该代码更改为printf("%p %d", &a, 0);
。 - 即使
a
没有const
,编译器也会被允许在寄存器中"缓存"a
的值。它只需要查找一次值,然后它知道a
永远不会更改*,因此它可以重用以前查找的值。
*编译器会做出很多假设,比如"此代码不会调用未定义的行为"。如果调用未定义的行为,编译器可能会做出一些"错误"的假设。在这种情况下,它可能确实如此。
缓冲区溢出是 UB,所以任何事情都可能发生。
此外,编译器可以优化 const 变量,因为它具有在编译时确定的常量值。
允许实现将 const
限定的对象完全放在不同的内存段中,因此这可能是它不受影响的原因(强调 may;由于缓冲区溢出的行为未定义,因此可能有很多原因)。
在线 C 2011 标准,第 6.7.3 节,脚注 132:
该实现可能会将未
volatile
的const
对象放置在 存储。此外,如果此类对象的地址为 从未使用过。
相关文章:
- 通过多个头文件使用常量变量
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 非常量变量只读位置的赋值
- 使用大量已知常量变量的正确方法
- 无法在具有常量变量大小的类中创建堆栈分配数组
- 这些语句是否等效(静态变量、常量变量和泛型)
- 包含常量变量并包含在多个文件中的标头的链接错误
- 我们如何修改常量变量的值
- 如何在模板类中设置静态常量变量
- 为什么常量变量是模板特殊化所必需的,而不是常量
- 如何在函数中传递常量变量?
- 定义常量变量的最佳方法
- C++ 声明常量变量,但推迟其初始化?
- 如何初始化具有常量变量的结构数组
- 使用常量变量作为维度将矩阵声明为类成员时出现编译器错误
- 使用指针 c++ 更改常量变量
- c++ 类中的静态常量变量和常量变量在存储方面是否有区别
- 为什么 lambda 对象中的局部变量是常量变量?
- 使用常量变量作为数组的大小
- 为许多类可能需要的所有常量变量制作独立的头文件是否是一种很好的做法?