如果两个指针的地址相同,则改变其中一个指针的值
我有一个问题,我看到两个指针的地址在这里是相同的( 两个指针的地址是相同的 ),也由蓝色月亮回答。 这让我更加怀疑。 由于两个指针都有相同的地址,我想改变其中一个指针的值,期望值也会在其他指针中改变(因为它们具有相同的地址)。 但它给出了分段错误。 我在下面的代码中显示它。
#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
。
现在来自你给出的蓝月亮链接答案
你应该总是将p
和p1
视为两个不同的指针(即使它们具有相同的内容),因为它们可能指向同一地址,也可能不指向同一地址。 您不应该依赖编译器优化。
代码
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
字符串文字存储在只读内存段中,因此尝试修改它会导致分段错误。 这是因为字符串文字数据可以被许多指针引用,修改它会修改其他常量字符串。