我想知道下面情况发生了什么:
我有以下功能:
void some_func(const int * a, int len_of_a) {
int * b = (int *) a;
b[1] = 3;
}
a是指向常量int的指针,所以据说我无法更改数组a中的任何内容。但我试图调整指针并更改内部元素。代码编译,当它运行时,当我传入一些常量数组时,我得到一个运行时异常。
我想知道究竟是什么导致了这个异常。该内存区域是否仅被操作系统标记为可读?或是否有一些硬件支持导致此异常?现场背后的是什么?
答案 0 :(得分:0)
在C ++中,它取决于a
实际指向的内容。如果它指向非const数据,则可以通过丢弃const来修改它。如果它指向声明为const
的内容,那么它就是undefined behaviour。
我不知道c是否也是如此。
const int a1[] = { 1, 2, 3 }
some_func(a1, 3); // undefined behaviour
int a2[] = { 1, 2, 3 }
some_func(a2, 3); // OK
这意味着如果您确切知道有关您正在处理的对象的所有内容,那么您应该只丢弃const。对于接受const
参数的一般函数,这显然不正确。
答案 1 :(得分:0)
根据一般规则,如果您尝试通过非const
类型的指针访问const
变量,请生成undefined behavior。
因此,您的程序行为将依赖于传递给some_func()
的参数类型。如果它是const
变量的地址,那么您的程序肯定会面向UB。为了更安全,如果您知道自己在做什么,请避免const
或避免修改const
。
在您的特定情况下,
当我传入一些常量数组时,我得到一个运行时异常。
你面对的是UB,因为数组是const
,你不应该改变那个数组的内容。
那就是说,你需要确保访问正确的内存。在您的函数内部,编译器无法知道b[1]
是否是有效访问。您需要确保访问有效,即指针被分配了足够的内存,以便b[1]
是通过该指针访问的有效元素。
相关,根据C11
标准,第6.7.3章,
如果尝试通过使用具有非const限定类型的左值来修改使用const限定类型定义的对象,则行为未定义。