我试图找出指向同一地址的两个指针的行为。为了自己尝试,我编写了下面的代码。这个让我困惑。这有什么区别?
#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);
}
这是输出。我在等输出就像“改变了!”并“改变了!”。 ptr
和copyPtr
应该指向同一个地址吗?当我更改此地址中的值时,它们应该都会更改,并且地址应保持相同。为什么不是这样?
另一方面,当完成动态内存分配时,似乎没有问题。
0x4007e4
0x4007e4
hey!
hey!
0x4007e4
0x4007ed
hey!
changed!
0xa9f420
0xa9f420
1
1
0xa9f420
0xa9f420
2
2
类似问题的答案并不能让我满意,或者这可能是一个重复的问题,因此我很抱歉......
答案 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 );
因此,在上面的代码片段中,更改了不同的值。在第一个例子中,改变了指针本身的值。
在第二个示例中,更改了指针指向的对象的值。指针本身的值没有改变。结果,两个指针仍指向同一个被更改的对象。