【问题标题】:How does this condition checking works?这种条件检查是如何工作的?
【发布时间】:2013-04-11 11:05:52
【问题描述】:

我写了一个通过指针反转字符串的函数,代码运行良好,没有错误,但有些事情我想知道。

这是我的代码:

char * xstrrev(char *s1, char *s2){
 register char *p = s1;
 register char *q = s2;
 char *r  = s2;
  do{

     *(s2++) = *(p++); //first copy the string, afterwards, replace it

  }while(*p);
  p--; //to eliminate trailing '\0' while reversing.
  do {
    *(q++) = *(p--); //replace contents by reverse contents,
  }while(*q);
  return r;
}

这里,在倒数第三行, *q 必须有一个值 '\0' ,因为我们之前复制了确切的字符串,所以,'\0' 必须已经复制了。

然而,当我更换我的

*(s2++) = *(p++);

p++;

即我只把p加到字符串的末尾,不把字符串复制到s2,条件

而(*q)

仍然有效。在这种情况下,*q 不应该有\0,对吧?那么这个条件是如何起作用的呢?

当我用while(*q!='\0')替换while(*q)时也是一样的

编辑::它被称为:

char  a[110]= "hello";
char f[116];
xstrrev(a,f); //reverse a and put to f
puts(f);

【问题讨论】:

  • 这是如此未定义的行为!将char f[116]; 更改为char f[116] = "helloworld"; 看看它是如何中断的。
  • 为什么将a 设置为回文?你怎么知道它是否真的被颠倒了? :)
  • @Barmar 任何其他字符串都一样,等等,我会编辑它。
  • 我的评论与问题无关,只是偶然。

标签: c pointers


【解决方案1】:

如果它起作用了,那完全是偶然的。调用者提供的字符串s2 可能在s2 的末尾有\0。但是你不能依赖这个,它取决于调用者如何初始化它传递的字符串。

另一种可能是a之前的内存权利恰好包含\0。如果您有以下情况,可能会发生这种情况:

char something[] = "foo";
char a[110] = "nacan";

something 的内存正好在a 的内存之前,因此something 的尾随空值将在a 的第一个字节之前。

在这种情况下发生的情况是循环复制了这个\0', but it doesn't stop immediately. It keeps on copying until it eventually runs in to a\0in*q. But when you look atf, you just see the reverse ofa`,因为这个空字节被复制了。

如果您想看到这种情况发生,请在调试器中单步执行您的函数。

C 语言无法保证这一切,它只是内存布局通常完成的方式。

【讨论】:

  • 不。调用者不提供。查看我的编辑。
  • 当您在函数开头的调试器中查看s2 时会看到什么?
  • 调用函数前f的值是多少?
  • 写入用户提供的字符串的函数应该被赋予输出字符串的长度,这样它们就不会超过它的结尾。这称为“缓冲区溢出”,是许多安全漏洞的原因。
  • 我认为这就是他所说的“必须检查”的意思。调用者告诉你长度,你确保你不会循环超过这个长度。
猜你喜欢
  • 2011-11-02
  • 1970-01-01
  • 2012-04-21
  • 1970-01-01
  • 1970-01-01
  • 2020-11-12
  • 1970-01-01
  • 2014-12-18
  • 1970-01-01
相关资源
最近更新 更多