我有一个问题,我看到两个指针的地址与此处的问题相同(Addresses of two pointers are same),也是由蓝月亮回答的。 这让我更加怀疑。由于两个指针都有相同的地址,我想改变其中一个指针的值,期望值也会在其他指针中改变(因为它们具有相同的地址)。但它给出了分段错误。我在下面的代码中显示它。
#include<stdio.h>
#include<string.h>
int main()
{
char * p = "abc";
char * p1 = "abc";
printf("%d\n %d\n", (void *)p, (void *)p1);
printf("%s\n %s\n", p, p1);
*p = 'b';
printf("%d\n %d\n", p, p1);
printf("%s\n %s\n", p, p1);
}
答案 0 :(得分:6)
C90,6.1.4
如果程序试图修改任何一种形式的字符串文字,那么 行为未定义。
在你的情况下,这种未定义的行为对你有利,这样你就会遇到Seg错误。除了这个使用%d
的打印指针不是一个好习惯,你应该使用%p
。
现在来自你给出的蓝月亮链接答案
您应始终将p
和p1
视为两个不同的指针(即使它们具有相同的内容),因为它们可能指向同一地址,也可能不指向同一地址。您不应该依赖编译器优化。
答案 1 :(得分:3)
char * p = "abc";
*p = 'b';
调用 未定义的行为 ,因为您正在尝试修改只读内存。您无法更改此常量字符串文字所在的内存。
使用此文字来初始化数组:
char myStr[] = "abc";
char *p = &myStr[0];
char *p2 = &myStr[0]; // <-- p and p2 point to the same address now
*p = 'b';
printf("%s\n", p2); // <-- prints bbc
答案 2 :(得分:3)
代码
char * p = "abc";
可以将字符串文字放在只读内存中,所以从技术上讲你不应该修改它。这可能会给你seg故障。这也是两个指针可能相同的原因......编译器足够聪明,可以识别它们都使用相同的字符串文字,因此只存储一个文字实例。
如果您将其声明为
char p[] = "abc"
然后这将在堆栈上创建一个可读/可写的4个字符(3和1空终止符)数组,然后您可以修改它,但是...
char p[] = "abc";
char p1[] = "abc";
你会发现p1 != p
因为两者都是在堆栈上创建了单独的存储空间(我假设它们不是全局变量)
使用printf
打印指针值时,我认为最好使用%p
。
答案 3 :(得分:2)
字符串文字存储在只读内存段中,因此尝试修改它会导致分段错误。这是因为字符串文字数据可以被许多指针引用,修改它会修改其他常量字符串。