为什么我在通过非常量指针变量改变const静态变量时会出现分段错误?

rjee0c15  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(97)
#include <stdio.h>

int main() {
    // case 1
    const int a = 10;
    int * ptr1 = &a;
    *ptr1 = 11;
    printf("%d\n",*ptr1);
    
    // case 2
    const static int b = 10;
    static int * ptr2 = &b;
    *ptr2 = 11;
    printf("%d\n",*ptr2);
    return 0;
}

字符串
在这个程序中,我可以理解的情况1(通过分配的地址的常量变量到一个非常数指针,我们可以改变变量的值)。如果我把同样的概念应用到情况2我不会工作。它给出了分段故障。什么是原因?是否有任何其他概念的情况2?在这里我使用gcc编译器。

q9rjltbz

q9rjltbz1#

通过尝试通过非常量指针修改const对象,将在程序中触发undefined behavior
这在C standard的第6.7.3p6节中详细说明:
如果试图通过使用非常量限定类型的左值来修改用常量限定类型定义的对象,则行为是未定义的。
当你的程序中有未定义的行为时,就不能保证它会做什么。它可能会崩溃(就像你的第二个例子),它可能会给出给予奇怪的结果,或者它可能看起来工作正常(就像你的第一个例子)。
所以这两种情况都有未定义的行为,只是表现方式不同而已。

9vw9lbht

9vw9lbht2#

在情况1中,a具有自动存储持续时间。自动存储持续时间通常使用硬件堆栈实现,除非优化将值保存在寄存器中或将其折叠到表达式中。堆栈不能是只读的,因为它用于许多非const的事情,因此C实现无法为a强制const。
在情况2中,b具有静态存储时间,并且它与其他const对象一起放入内存区域。该内存被标记为只读(在初始化后),这强制执行const属性。
此行为特定于您的C实现和特定环境,并可能随环境的变化而变化。它不是由C标准定义的。

相关问题