3

考虑这段代码。

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
}

有 2 个字符串st. 首先我设置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 foobar foo.

为什么在这种情况下没有改变?

4

3 回答 3

12

这是未定义的行为,这意味着任何事情都可能发生:

char *s, *t;
strcpy(s, "foo");

就像strcpy()写入内存中的随机位置一样,因为s它是一个未初始化的指针。


在更正未定义行为的编辑后

问题 1 - 为什么在这种情况下 t 的值会发生变化?(我将“bar”复制到为什么没有改变)。

这是一个指针赋值:

t = s;

并导致两者都t指向s与之前malloc()分配的相同内存st通过和可以看到对该内存的任何更改s

问题 2 - 为什么在第二种情况下没有改变?

这将字符串文字的地址分配"bar"s

s = "bar";

所以现在t不要s指向同一个内存位置。t指向较早malloc()并​​分配给的内存s(由于t = s;指针分配)。

strcpy()并且=非常不同

  • strcpy()将字符复制到其第一个参数指定的内存地址
  • 赋值, =, 改变指针持有的地址
于 2013-05-20T14:16:18.490 回答
2
strcpy(s, "foo");

复制foos t = s 指向的内存位置;现在,t两者s都指向相同的位置因此,相同的输出

现在,您复制bars. 因为两者都t指向s同一个位置。因此,再次输出相同的输出。


直到这条线一切都一样

s = "bar"

您创建一个字符串常量bar。并将其地址分配给s。它pointer可以指向任何内存位置。不一定是原来的。

现在,

s指向bar并且t仍然指向它在开始时指向的较早位置,因此输出

于 2013-05-20T14:27:14.607 回答
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

现在 t 仍然指向地址 123,这就是为什么 t, s 都打印 bar 。

       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 给出不同的值。

于 2013-05-21T05:26:39.063 回答