【发布时间】:2021-12-30 20:43:07
【问题描述】:
观察以下代码:
const char *str1 = "foo";
printf("1.1: %s\n", str1);
str1 = "bar";
printf("1.2: %s\n\n", str1);
const char *str2[] = { "foo", "bar" };
printf("2.1: %s\n", str2[0]);
str2[0] = "baz";
printf("2.2: %s\n\n", str2[0]);
char *str3 = malloc(4);
strcpy(str3, "foo");
const char *str4[] = { str3, "bar" };
printf("3.1: %s -- %s\n", str4[0], str4[1]);
//str4[0][0] = 'z';
str4[0] = "bar";
str4[1] = "baz";
printf("3.2: %s -- %s\n", str4[0], str4[1]);
free(str3);
将其包装在标准的main 函数中并使用gcc -Wall -Wextra -o test test.c 进行编译,这不会给出警告,输出为:
1.1: foo
1.2: bar
2.1: foo
2.2: baz
3.1: foo -- bar
3.2: bar -- baz
当取消注释唯一的注释行时,gcc 会抱怨 error: assignment of read-only location ‘*str4[0]’。当然这是意料之中的,我只是为了完整而添加了那一点。
据我了解,所有其他分配都是有效的,因为我没有修改已经存在的只读内存,而是将其全部替换为 另一个 内存块(这也是标记为只读)。但这在所有 C 编译器中都是合法的,还是仍然依赖于实现,因此会导致未定义的行为?很难找到这方面的好信息,因为它似乎总是关于通过指针魔术修改现有内存或将const 扔掉。
【问题讨论】:
-
您不是在“替换”内存,而是在使指针指向不同的内存位置。该操作是有效的,因为指针本身不是
const -
您不是在修改或“替换”(无论这意味着什么)任何只读内存——您正在修改不是 const 的指针,因此不在只读内存中。您可能在脑海中混淆了指针的内存和指针指向的内存——这是两个不同的位置。
-
是的,我不知道怎么称呼它,“替换”我的意思是“让它指向不同的(只读)内存”。我并不是要暗示相同的内存部分被不同的内容替换。
标签: c pointers constants declaration string-literals