发生的事情是你mallocing 两个内存块。这些块有地址,d 和 e 持有。要确认这一点,请将这些放在您的 scanfs 之后。
printf ("Address of d: %p\n", &d);
printf ("Address of e: %p\n", &e);
printf ("Address of block d(value of d): %p\n", d);
printf ("Address of block e(value of e): %p\n", e);
我的输出是:
Address of d: 0x7fff037a5488
Address of e: 0x7fff037a5490
Address of block d(value of d): 0xa8e010
Address of block e(value of e): 0xa8e030
现在,当您在指针之间进行交换时,您所做的只是更改内存块引用,而不是实际的指针地址(您不能这样做强>)。
您可以通过将这些 printf 放在交换之后来确认,如下所示:
#include<stdio.h>
#include<stdlib.h>
int main()
{
char *d,*e,*f;
d=(char*)malloc(10);
e=(char*)malloc(5);
scanf("%s",d);
scanf("%s",e);
printf ("Address of d: %p\n", &d);
printf ("Address of e: %p\n", &e);
printf ("Address of f: %p\n", &f);
printf ("Address of block d(value of d): %p\n", d);
printf ("Address of block e(value of e): %p\n", e);
f=d;
d=e;
e=f; //while printing e it prints the whole value contained in f (i.e.1ellohai). How? size of e is 5 only
printf ("Address of d: %p\n", &d);
printf ("Address of e: %p\n", &e);
printf ("Address of f: %p\n", &f);
printf ("Address of block d(value of d): %p\n", d);
printf ("Address of block e(value of e): %p\n", e);
printf ("Address of block f(value of f): %p\n", f);
f[0]='1'; // f is in read-only memory. So this should fail?
printf("%s \t %s \t %s \n",d,e,f);
return 0;
}
还有输出:
$ ./draft
hellohai
asd
Address of d: 0x7ffebae87d78
Address of e: 0x7ffebae87d80
Address of f: 0x7ffebae87d88
Address of block d(value of d): 0x2143010
Address of block e(value of e): 0x2143030
Address of d: 0x7ffebae87d78
Address of e: 0x7ffebae87d80
Address of f: 0x7ffebae87d88
Address of block d(value of d): 0x2143030
Address of block e(value of e): 0x2143010
Address of block f(value of f): 0x2143010
asd 1ellohai 1ellohai
从这里可以看出:
-
- 指针的地址从未改变。
-
-
references(它们的值)发生了变化。他们被交换了。
-
-
e 和 f 指向同一个内存块。这就是为什么 f[0]='1' 会改变两者打印的值。
原始内存布局
声明变量后,您的内存将如下所示:
Values : | - | - | - | | | |
Variable : | d | e | f | | | |
Memory(hex): | 1 | 2 | 3 | 4 | 5 | 6 |
当你 malloc 时,你的计算机将地址 5 处的块分配给d,并将地址 6 处的块分配给e,所以现在它看起来像这样:
Values : | 5 | 6 | - | | | |
Variable : | d | e | f | | | |
Memory(hex): | 1 | 2 | 3 | 4 | 5 | 6 |
读取字符串后,5 和 6 处的块的内容 将被写入:
Values : | 5 | 6 | - | | hellohai | asd |
Variable : | d | e | f | | | |
Memory(hex): | 1 | 2 | 3 | 4 | 5 | 6 |
当您打印d 时,它会访问它指向的内存地址(在本例中为5)并打印内容。 e 变量也是如此。
现在,当您交换价值观时:
f=d;
Values : | 5 | 6 | 5 | | hellohai | asd |
Variable : | d | e | f | | | |
Memory(hex): | 1 | 2 | 3 | 4 | 5 | 6 |
d=e;
Values : | 6 | 6 | 5 | | hellohai | asd |
Variable : | d | e | f | | | |
Memory(hex): | 1 | 2 | 3 | 4 | 5 | 6 |
e=f;
Values : | 6 | 5 | 5 | | hellohai | asd |
Variable : | d | e | f | | | |
Memory(hex): | 1 | 2 | 3 | 4 | 5 | 6 |
现在e 和f 指向同一个地方(d 曾经指向的地方)和d 指向e 曾经的地方> 点。 需要注意,地址5和6的实际值从未被触及。
当你这样做时:
f[0]='1';
您告诉计算机访问地址 5 处内存块内容的第一个字节并更改它。所以现在你有:
Values : | 6 | 5 | 5 | | 1ellohai | asd |
Variable : | d | e | f | | | |
Memory(hex): | 1 | 2 | 3 | 4 | 5 | 6 |
这是您记忆的样子的一个非常简单的表示,因此您可以了解它是如何工作的。