我不太了解黑客,c,汇编,记忆和所有这些东西,所以我不能自己解决我的问题。
因此,缓冲区溢出溢出到其他变量地址并破坏它们。所以我测试了它确实如此。而且我认为如果它可以溢出常量变量缓冲区溢出必须超级供电并且我测试过,但它不会溢出const变量。
为什么?
int a;
char buffer[8];
和
const int a;
char buffer[8];
通过'buffer'的大小在变量'a'的地址前面有变量'buffer'的地址。在分配给内存时,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]: %s\n",buffer2,buffer2);
printf("a [%p]: %d\n",&a,a);
printf("Buffer 1 [%p]: %s\n",buffer1,buffer1);
printf("\nCopy Buffer\n\n");
strcpy(buffer2,"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
printf("Buffer 2 [%p]: %s\n",buffer2,buffer2);
printf("a [%p]: %d\n",&a,a);
printf("Buffer 1 [%p]: %s\n",buffer1,buffer1);
return 0;
}
答案 0 :(得分:5)
我想到了三件事:
a
是什么。如果我是编译器,我会查看该代码并说“a
始终为零,所以我只是继续将a
替换为0
。”问题是,当你说printf("%p %d", &a, a);
时,编译器甚至不必获取a
的内容。它知道它将永远为零。*因此它可以将代码更改为printf("%p %d", &a, 0);
。a
不是const
,编译器也可以在寄存器中“缓存”a
的值。它只需要查找一次值,然后它知道a
永远不会改变*,所以它可以重用它之前查找的值。*编译器会做出很多假设,比如“此代码不会调用未定义的行为”。如果调用未定义的行为,编译器可能会做出一些“错误”的假设。在这种情况下,它可能会这样做。
答案 1 :(得分:1)
缓冲区溢出是UB,因此任何事情都可能发生。
此外,您的编译器可以优化您的const变量,因为它具有在编译时确定的常量值。
答案 2 :(得分:1)
允许实现将const
限定对象放在不同的内存段中,这样可能成为不受影响的原因(强调可能< / em>;因为缓冲区溢出的行为未定义,可能有许多原因)。
Online C 2011 standard,第6.7.3节,脚注132:
实现可能会将
const
对象放在volatile
的只读区域中 存储。此外,如果其地址是,则实现不需要为这样的对象分配存储 从未使用过。