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

时间:2013-09-30 09:32:59

标签: c pointers literals

我有一个问题,我看到两个指针的地址与此处的问题相同(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);
}

4 个答案:

答案 0 :(得分:6)

  

C90,6.1.4

     

如果程序试图修改任何一种形式的字符串文字,那么   行为未定义。

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

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

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

答案 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)

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