【问题标题】:Getting segmentation fault in Linux when running my C program运行我的 C 程序时在 Linux 中出现分段错误
【发布时间】:2013-04-24 15:37:22
【问题描述】:

我正在尝试在Red Hat Linux 中模拟cat 命令。我运行程序时收到segmentation fault

例如:

./a.out a > b

a 包含你好。我希望你好被复制到b

我的代码如下:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

int main(int argc,char *argv[])
{
    int f, fd, r;
    char buf[100];

    if (argc < 2)
    {
        printf("Error");
        return 0;
    }
    else
    {
        if (!strcmp(argv[2],">"))
        {
            f = open(argv[1],0,00777);

            if (f == -1)
                printf("no file");
            else
            {
                fd = creat(argv[3],00777);
                while( (r = read(f,buf,50)) > 0)
                    write(fd, buf, r);
            }
        }
    }
    return 0;
}

为什么会出现分段错误?

我有一个类似的程序,我在其中以相同的方式打开和创建文件,并且该程序正在运行,但是这个程序给了我一个分段错误。

【问题讨论】:

  • gdb 被发明的众多原因之一。
  • @WhozCraig - 现在,如果他们只能继续讨论 gdb 需要改进并变得更加易用和友好的众多原因之一。
  • 不要浪费你的生命手工格式化代码;使用计算机程序。 en.wikipedia.org/wiki/Indent_(Unix)
  • @Duck 所有主要的 IDE 都对 GDB 有很好的支持,包括调用堆栈和变量的可视化处理。
  • 然后gdb-g 组合在你的编译命令行参数上会非常方便。

标签: c linux simulation


【解决方案1】:

Joachim Pileborg 的回答显然是正确的,只需尝试将您的程序运行为

./a.out a \> b

防止外壳将“>”解释为重定向。

【讨论】:

  • 感谢这工作。我无法理解在早期的程序中我给了 ./a.out a > b 它在该程序中的工作正常。但是不在这个程序中是不是很奇怪。
  • 您的程序仍然是错误的,正如其他人所说,在 argc 测试中。如果要访问 argv[3],则必须在 argc
【解决方案2】:

你可以在没有gdb 的情况下生活 - 但你必须开始以结构化的方式解决问题:

  • 不要把任何事情视为理所当然。例如,即使您将程序称为program &gt; file,也不要假设argv 看起来像您假设的那样,而是通过输出它们中的每一个来检查它:

    printf("argc: %d\n", argc);
    printf("argv[0]: %s\n", argv[0]);
    printf("argv[1]: %s\n", argv[1]);
    printf("argv[2]: %s\n", argv[2]);
    printf("argv[3]: %s\n", argv[3]);
    // the se can be expressed better with a for loop - but I'll leave that as an exercise for you
    
  • 仅将您已验证的事情视为理所当然:如果您知道argc &gt;= 2,请不要访问argv[2] 和/或argv[3]

  • 别说

    if(argc<2)
    {
        printf("Error");
        return 0;
    }
    

    但是

    if(argc<2) // according to the point before, better y3 or <4
    {
        printf("Too few command line arguments");
        return 1; // not 0; 0 would mean success
    }
    

【讨论】:

  • 我也在想同样的事情,这个简单的 gdb 程序已经结束了,一些快速打印将隔离问题。
  • @Mike 仅据 OP 了解,他会在名为 b 的文件中找到所有打印,而不是在屏幕上。实际上,错误(和调试)消息应该发送到 stderr 而不是 stdout。
【解决方案3】:

这可能是因为重定向是由shell而不是你的程序处理的,所以argv[2]NULLargv[3]不存在。

但是,您应该使用调试器来找出实际发生的情况。然后添加适当的错误检查。

【讨论】:

  • +1 用于了解标准规定 argv[argc] 保证为 NULL(您可能不会对它被解释为未定义的频率感到惊讶)。
  • 一周前我做了一个类似的程序,它运行良好。不知道为什么我只在这个程序中得到这个错误
  • @ashwinbhy 那么它可能正在工作,因为它相似。重定向和管道总是由 shell 处理。
  • 几乎一样。在这里我只检查我为“>>”等制作的另一个程序中的一个条件。它现在在同一台电脑上工作正常我正在比较两者我使用完全相同的东西但是这个程序不起作用
  • 实际上我不知道如何使用调试器,我对 linux 还很陌生。我必须在明天的测试之前再执行 20 个程序,所以暂时不要这样做。
猜你喜欢
  • 2013-11-30
  • 2013-09-13
  • 2021-07-03
  • 2021-06-03
  • 2021-07-18
  • 1970-01-01
  • 2015-03-20
  • 1970-01-01
相关资源
最近更新 更多