如果两个指针的地址相同,则改变其中一个指针的值

我有一个问题,我看到两个指针的地址在这里是相同的( 两个指针的地址是相同的 ),也由蓝色月亮回答。 这让我更加怀疑。 由于两个指针都有相同的地址,我想改变其中一个指针的值,期望值也会在其他指针中改变(因为它们具有相同的地址)。 但它给出了分段错误。 我在下面的代码中显示它。

#include #include 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); } 

C90,6.1.4

如果程序试图修改任一表单的字符串文字,则行为未定义。

在你的情况下,这种未定义的行为对你有利,所以你得到Seg错误。除了这个使用%d打印指针不是一个好习惯,你应该使用%p

现在来自你给出的蓝月亮链接答案

你应该总是将pp1视为两个不同的指针(即使它们具有相同的内容),因为它们可能指向同一地址,也可能不指向同一地址。 您不应该依赖编译器优化。

代码

 char * p = "abc"; 

可以将字符串文字放在只读内存中,所以从技术上讲你不应该修改它。 这可能会给你seg故障。 这也是两个指针可能相同的原因…编译器足够聪明,可以识别它们都使用相同的字符串文字,因此只存储文字的一个实例。

如果你声明它

 char p[] = "abc" 

然后,这将在堆栈上创建一个包含4个字符(3和1空终止符)的可读/可写数组,然后您可以修改它,但是……

 char p[] = "abc"; char p1[] = "abc"; 

你会发现p1 != p因为它们都是在堆栈上创建了单独的存储空间(我假设它们不是全局变量)

另外,当使用printf打印指针值时,我认为最好使用%p

 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 

字符串文字存储在只读内存段中,因此尝试修改它会导致分段错误。 这是因为字符串文字数据可以被许多指针引用,修改它会修改其他常量字符串。