【问题标题】:Segfault with strcmpstrcmp 的段错误
【发布时间】:2011-09-12 05:09:19
【问题描述】:

我通过以下方式使用 strcmp

  1. 传递 char[] 数组名称
  2. 将指针传递给字符串字面量 但是,第二个导致段错误。即使我已经确认指针指向正确的字符串文字,但我对为什么会出现段错误感到困惑.. 这是代码:-

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, char const *args[])
    {
      char firstName[strlen(*++args)];
      strcpy(firstName, *args);
      char lastName[strlen(*++args)];
      strcpy(lastName, *args);
      printf("%s\t%s\n", firstName, lastName);
    
      printf("%d\n", strcmp(firstName, lastName));// this works
    
      printf("%d\n", strcmp(*(--args),*(++args)));//this gives me a seg fault
    
      return EXIT_SUCCESS;
    }
    

我将它保存为 str.c,当我编译它时,首先我收到以下警告:

[Neutron@Discovery examples]$ gcc -Wall str.c -o str

str.c: In function ‘main’:
str.c:15: warning: operation on ‘args’ may be undefined

最后运行它,给出如下所示的段错误

[Neutron@Discovery examples]$ ./str Jimmy Neutron


Jimmy   Neutron

-4

Segmentation fault (core dumped)

【问题讨论】:

  • 对此投票“过于本地化”毫无意义。它可以说是stackoverflow.com/questions/7877258/… 的副本,因为真正的问题是“这个警告是什么意思?”但过于本地化只是反常:无益且没有抓住重点。

标签: c evaluation strcmp args sequence-points


【解决方案1】:

当您将同一个变量作为两个不同的参数两次传递给同一个函数时,不要使用--++

而不是printf("%d\n", strcmp(*(--args),*(++args)));

char *first = *(--args);
char *second = *(++args);
printf("%d\n", strcmp(first,second));

仍然不是真正可读(最好使用索引并检查 argc 的有效性),但至少您不会更改该值并在同一序列点对其进行多次评估。

【讨论】:

  • @Jimm:C 不保证任何评估顺序。它通常不是从左到右的。在同一语句中多次修改变量是未定义的行为。
  • @Jimm,是的,但是您正在更改值并同时评估它们,这是未定义的行为。
  • 修改的是指针变量args,序列点之间不能修改多次。
  • 感谢您将序列点告诉我。这是缺少的链接,这让我很难理解 littleadv 的 cmets。在维基百科上查看序列点en.wikipedia.org/wiki/Sequence_point 后,它实际上在它的引用中告诉了确切的子句
  • 阅读comp.lang.c FAQ 的第 3 部分。然后阅读其余部分。
【解决方案2】:

除了 littleadv 的帖子所说的之外,您的缓冲区太短了一个字符(它没有为空终止符留下任何空间)。因此,您的 strcpy 会导致缓冲区溢出。

【讨论】:

  • 奇怪,即使 strcmp 是一个不受限制的字符串函数,上面的代码也适用于没有 NULL 字符的字符数组。只有当我使用指针执行 strcmp 时,才会出现段错误。
  • @Jimm:它仍然是未定义的行为,因为缓冲区溢出仍然发生(它写入一个空终止符;它只会在外部你的缓冲区的边界)。在这种情况下,你很幸运,缓冲区溢出没有更早地杀死你的程序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-11
  • 1970-01-01
  • 2015-08-14
  • 2018-10-08
  • 1970-01-01
  • 1970-01-01
  • 2021-06-11
相关资源
最近更新 更多