考虑这段代码。
int main()
{
char *s, *t;
s = malloc(4 * sizeof(char));
strcpy(s, "foo");
t = s;
printf("%s %s\n", s, t); // Output --> foo foo
strcpy(s, "bar"); // s = "bar"
printf("%s %s\n", s, t); // Output --> bar bar
}
有两个字符串s
和t
。首先,我将s
设置为"foo"
,然后将t
指向s
。当我打印字符串时,我得到foo foo
。
然后,将"bar"
复制到s
并再次打印,我得到bar bar
。
为什么t
的值会在这种情况下发生变化? (我将"bar"
复制到s
为什么t
更改了。
现在我将strcpy(s, "bar")
更改为s = "bar"
-
int main()
{
char *s, *t;
s = malloc(4 * sizeof(char));
strcpy(s, "foo");
t = s;
printf("%s %s\n", s, t); // Output --> foo foo
s = "bar"
printf("%s %s\n", s, t); // Output --> bar foo
}
此代码为我提供了foo foo
和bar foo
。
为什么在这种情况下没有改变?
答案 0 :(得分:12)
这是undefined behaviour,这意味着任何事情都可能发生:
char *s, *t;
strcpy(s, "foo");
因为strcpy()
正在写入内存中的随机位置,因为s
是未初始化的指针。
(编辑后纠正未定义的行为)
问题1 - 在这种情况下,为什么t的值会发生变化? (我复制了“bar”,为什么没有改变)。
这是一个指针赋值:
t = s;
并导致t
和s
指向同一内存malloc()
且之前已分配给s
的内存。通过t
和s
可以看到对该内存的任何更改。
问题2 - 为什么在第二种情况下不改变?
这会将字符串文字"bar"
的地址指定给s
:
s = "bar";
所以现在t
和s
没有指向相同的内存位置。 t
指向早先malloc()
并分配给s
的内存(由于t = s;
指针分配)。
strcpy()
和=
非常不同:
strcpy()
将字符复制到其第一个参数=
,更改指针所包含的地址答案 1 :(得分:2)
strcpy(s, "foo");
将foo
复制到s
指向的内存位置
t = s;
现在,t
和s
都指向同一位置
因此,相同的输出
现在,您将bar
复制到s
。由于t
和s
都指向同一位置。因此,再次输出相同的数据。
这条线上的一切都是一样的
s = "bar"
您创建一个字符串常量bar
。并将其地址分配给s
。它是一个pointer
它可以指向任何内存位置。不一定是原来的。
现在,
s
指向bar
和t
仍然指向它在开头指向的早期位置,因此输出
答案 2 :(得分:2)
一种简单的理解方式如下: -
s = malloc(4 * sizeof(char)); // this will be interpreted as follows
s = 123 ------------>| | | | | //some garbage values at these location
123 124 125 126 // some random address chosen.
strcpy(s, "foo") ; // it copies at the address provided by s i.e.
|'f'|'o'|'o'|'\0'|
123 124 125 126
t = s; this statement means t it pointing to address = 123
strcpy(s, "bar"); // this statement copies at given address it means it will override previous value . i.e
|'b'|'a'|'r'|'\0'|
123 124 125 126
现在仍然指向地址123,这就是为什么t,s都打印条形码。
s = "bar" // this will assign a new address to s which is base address of "bar" string . i.e .
|'b'|'a'|'r'|'\0'|
321 322 323 324
现在s将包含地址321,而t具有值123,这就是s和t给出不同值的原因。