在指向同一位置的两个指针时更改值

时间:2017-05-25 17:44:52

标签: c pointers

我试图找出指向同一地址的两个指针的行为。为了自己尝试,我编写了下面的代码。这个让我困惑。这有什么区别?

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *ptr = "hey!";
    char *copyPtr = ptr;

    printf("%p\n", ptr);
    printf("%p\n", copyPtr);

    printf("%s\n", ptr);
    printf("%s\n", copyPtr);

    copyPtr = "changed!";

    printf("%p\n", ptr);
    printf("%p\n", copyPtr);

    printf("%s\n", ptr);
    printf("%s\n", copyPtr);

    printf("\n\n");

    int *ptr1 = malloc(sizeof(int));
    *ptr1 = 1;
    int *copyPtr1 = ptr1;

    printf("%p\n", ptr1);
    printf("%p\n", copyPtr1);

    printf("%d\n", *ptr1);
    printf("%d\n", *copyPtr1);

    *copyPtr1 = 2;

    printf("%p\n", ptr1);
    printf("%p\n", copyPtr1);

    printf("%d\n", *ptr1);
    printf("%d\n", *copyPtr1);

    free(ptr1);
}

这是输出。我在等输出就像“改变了!”并“改变了!”。 ptrcopyPtr应该指向同一个地址吗?当我更改此地址中的值时,它们应该都会更改,并且地址应保持相同。为什么不是这样?

另一方面,当完成动态内存分配时,似乎没有问题。

0x4007e4
0x4007e4
hey!
hey!
0x4007e4
0x4007ed
hey!
changed!


0xa9f420
0xa9f420
1
1
0xa9f420
0xa9f420
2
2

类似问题的答案并不能让我满意,或者这可能是一个重复的问题,因此我很抱歉......

4 个答案:

答案 0 :(得分:2)

在第一种情况下,您将copyPtr更改为字符串常量的地址。此字符串常量与第一个字符串不同。因此,在此更改之后,指针值会不同,就像它们指向的那样。

在第二种情况下,您实际上并没有更改copyPtr1。您取消引用它并将指向的值更改为,这与ptr1指向的值相同。因此,当您取消引用ptr1时,会反映价值的变化。在这种情况下您使用malloc这一事实无关紧要。相关的是你在这种情况下取​​消引用指针,而在前者你没有取消引用。

为了让第一个案例在ptr中显示更改,您需要取消引用copyPtr而不是更改其值。但请注意,字符串常量只是 - 常量。您无法更改它们,尝试这样做可能会导致分段错误。另一方面,如果指向的内存是动态创建的,那么您可以更改它。

例如,这是无效的:

char *ptr = "hey!";
char *copyPtr = ptr;
strcpy(copyPtr, "hi!");    // invalid: attempt to write to a string constant

但这会奏效:

char *ptr = strdup("hey!");
char *copyPtr = ptr;
strcpy(copyPtr, "hi!");    // OK, but be careful not to overrun the buffer

答案 1 :(得分:1)

第一次更改 - copyPtr = "changed!";和第二次更改 - *copyPtr1 = 2;

之间存在差异

虽然第一个将copyPtr的地址更改为指向目标文件中的const部分(.ro部分),而第二个保持指针copyPtr1指向堆中的相同内存,但只修改它的内容。希望有所帮助!

答案 2 :(得分:0)

代码:

copyPtr = "changed!";

将指针更改为指向新的字符串文字,如输出中所示:

0x4007e4
0x4007ed
hey!
changed!

如果要更改原始地址的值,请使用strcpy()。

在你使用malloc内存的第二个中,你正在取消引用指针,所以值按预期变化(而不是指针)。

答案 3 :(得分:0)

在此声明中

copyPtr = "changed!";

更改了指针copyPtr本身存储的值。

现在指针指向字符串文字"changed!"的第一个字符。

在本声明中

*ptr1 = 1;

更改了指针ptr1指向的对象,因为在语句中指针被解除引用。指针本身的值没有改变。它仍然在语句

中保留已分配内存的地址
int *ptr1 = malloc(sizeof(int));

您可以使用之前的指针获得相同的结果。例如

char s[] = "hey!";
char *ptr = s;
char *copyPtr = ptr;

// ...

*copyPtr = 'H';

puts( ptr );
puts( copyPtr );

因此,在上面的代码片段中,更改了不同的值。在第一个例子中,改变了指针本身的值。

在第二个示例中,更改了指针指向的对象的值。指针本身的值没有改变。结果,两个指针仍指向同一个被更改的对象。