为什么我在这里遇到分段错误? [C]

时间:2016-01-14 06:16:58

标签: c segmentation-fault

这将获得负面投票但我甚至不关心,只要有人可以帮助我。我无法访问调试器,如果我这样做,我可以在几小时前完成。

为什么我在这里遇到分段错误?这是不是意味着我试图访问一些不属于我的进程的内存位置?我应该在将数据从一个文件复制到下一个文件之前实现一个缓冲区(虽然我不知道它为什么会重要)?

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

int error( char * msg )
{
    perror( msg );
    return 2;
}

int usage( char * name )
{
    printf( "Usage: %s <file to copy> <name of copy>\n", name );
    return 1;
}

int main( int argc, char * argv[] )
{
    //making sure all required arguments have been passed
    if ( argc != 3 )
        return usage( argv[0] );

    //Make sure input exists, make sure output does not exist
    char *inputFname = argv[1];
    char *outputFname = argv[2];
    FILE *inputFile;
    FILE *outputFile;
    inputFile = fopen(inputFname, "r");
    int err = errno;
    outputFile = fopen(outputFname, "r");

    //handle file opening errors
    if(outputFile != NULL){
        return error("Error: target file already exists\n");
        fclose(outputFile);
    }
    if(inputFile == NULL && err == 2){
        //errno of 2 corresponds to error code ENOENT; no such file or directory
        return error("Error: file does not exist\n");
        fclose(inputFile);
    }
    if(inputFile == NULL && err ==  19){
        //errno of 19 corresponds to error code EACCE; permission error
        return error("Error: permission denied for file\n");
        fclose(inputFile);
    }
    fclose(outputFile);

    //no errors upon opening, gather info and make buffer
    printf("No errors, proceeding with copy");
    struct stat info;
    stat(inputFname, &info);

    //create new file
    outputFile = fopen(outputFname, "w");
    chmod(outputFname, info.st_mode & 07777);

    //copy the contents
    char nextChar;
    while( (nextChar = fgetc(inputFile)) != EOF)
        fputc(nextChar, outputFile);

    printf("copy completed");
    return 0;
}

2 个答案:

答案 0 :(得分:0)

  1. fclose(outputFile);
    这就是错误。如果outputFile为NULL,该怎么办?即目标文件尚不存在(理想条件)?

    man -s3 fclose

      

    如果stream参数是非法指针,则fclose()的行为是未定义的。

    1. main返回后,您认为fclose会如何运作?

      return error("Error: target file already exists\n");
      fclose(outputFile);

      1. 如果inputFileNULLerrno既不是2也不是19,该怎么办?

        提示:在这种情况下,前两个if将不会退出main,程序将继续通过inputFile = NULL的文件错误检查代码。

        1. 此外,您还没有关闭副本完成的流。
        2. 我认为编写此代码的最佳方法是在打开输入文件后立即检查inputFile的错误。如果NULL然后退出,则继续。

          然后同样检查输出文件。如果 NOT NULL然后退出,则继续。

          所以正确的代码片段是:

          ...
          inputFile = fopen(inputFname, "r");
          int err = errno;
          
          if(inputFile == NULL)
          { 
              if (err == 2)
                  return error("Error: file does not exist\n");
          
              if(err ==  19)
                  return error("Error: permission denied for file\n");
          
              return error("Other Error");
          }
          
          outputFile = fopen(outputFname, "r");
          if(outputFile != NULL)
          {
              fclose(inputFile);
              fclose(outputFile);
              return error("Error: target file already exists\n");
          }  
          ...  
          printf("copy completed");  
          fclose(inputFile);
          fclose(outputFile);
          return 0;
          

答案 1 :(得分:-2)

我可以,而且可能应该,只是删除这个低质量的问题,但我想出来并且我将回答我自己的问题,因为似乎人们经常会问这个完全相同的事情;也许这会有所帮助。

问题是我在检查错误后调用fclose()。我以为我正在关闭最近打开的文件outputFile。但实际上我完全摆脱了FILE指针*outputFile。所以,稍后,当我尝试将另一个文件打开到同一个FILE指针时,指针就消失了,因此出现了分段错误。这就是我以面向对象的方式思考的结果!