gpt4 book ai didi

c - 修改 const char 数组引用的非常量 char 数组

转载 作者:行者123 更新时间:2023-12-02 00:53:33 25 4
gpt4 key购买 nike

考虑以下代码:

struct ns_test{
char *str;
};

struct ns_test *ns_test_alloc(char *str){
struct ns_test *nt = malloc(sizeof(*nt));
nt->str = str;
return nt;
}

const char *ns_test_get_str(struct ns_test *tst){
return tst->str;
}

void ns_test_release(struct ns_test* tst){
free(tst);
}

void ns_test_set_char(struct ns_test *tst, size_t i, char c){
tst->str[i] = c;
}

int main(void){
char arr[] = "1234567890";
struct ns_test *ns_test_ptr = ns_test_alloc(arr);
const char *str = ns_test_get_str(ns_test_ptr);
printf("%s\n", str); //1234567890
ns_test_set_char(ns_test_ptr, 4, 'a');
printf("%s\n", str); //1234a67890
}

问题是:代码的行为是否未定义?

我认为是。

标准在 6.7.3(p6) 中指定:

If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined.

因此,为了避免这种 UB,我们需要 const char *ns_test_get_str(struct ns_test *tst) 来复制 char *str。但要点是避免复制并将修改限制为唯一的 void ns_test_set_char(struct ns_test *tst, size_t i, char c) 这可能会先进行一些完整性检查或其他操作。

最佳答案

这里的关键是“用 const 限定类型定义的对象”。重要的是您如何定义(IOW,“为其分配内存”)所指向的对象。如果“对象”不是作为 const“创建”的,那么无论您使用多少个 const 或非常量指针和引用都没有关系 - 您仍然可以修改它。

所以,

const int i = 0;
int *p = (int*)&i;
*p = 1;

是 UB。

同时

int i = 0;
const int *cp = &i;
int *p = (int*) cp;
*p = 1;

很好。

我怀疑这甚至可以与 new 一起使用:

const int *cp = new const int(0);
int *p = (int*) cp;
*p = 1;

在技术上是 UB。

它确实在 cpp.sh 上编译时没有警告,但这并不意味着什么。

更新:正如 Christian Gibbons 所指出的,问题中的语言是 C,因此关于 new 运算符的部分不适用。 malloc() 和 friend 永远不会是 const

稍微扩展一下 - 以这种方式编写标准的一个可能原因是让编译器可以自由地将只读内存用于 const 值。在那种情况下,写入这些位置会变成崩溃或空洞。换句话说,UB。

关于c - 修改 const char 数组引用的非常量 char 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56046844/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com